Пример #1
0
    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
Пример #2
0
def test__solve():
    # Has keys [model, sfield, efield, solver_opts]
    dat = REGRES['res']
    inp = {
        'model': emg3d.Model(**dat['input_model']),
        'sfield': emg3d.get_source_field(**dat['input_source']),
        'efield': None,
        'solver_opts': {
            'plain': True
        }
    }
    efield, info = solver._solve(inp)
    assert_allclose(dat['Fresult'].field, efield.field)

    # Has keys [model, grid, source, frequency, efield, solver_opts]
    dat = REGRES['res']
    model = model = emg3d.Model(**dat['input_model'])
    inp = {
        'model': model,
        'grid': model.grid,
        'source': dat['input_source']['source'],
        'frequency': dat['input_source']['frequency'],
        'efield': None,
        'solver_opts': {
            'plain': True
        }
    }
    efield, info = solver._solve(inp)
    assert_allclose(dat['Fresult'].field, efield.field)
Пример #3
0
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)
Пример #4
0
    def test_cycle_gcrotmk(self, capsys):

        # Load any case.
        dat = REGRES['res']
        model = emg3d.Model(**dat['input_model'])
        grid = model.grid
        sfield = emg3d.get_source_field(**dat['input_source'])
        vmodel = emg3d.models.VolumeModel(model, sfield)
        efield = emg3d.Field(grid)  # Initiate e-field.

        # Get var-instance
        var = solver.MGParameters(
            cycle='F',
            sslsolver='gcrotmk',
            semicoarsening=False,
            linerelaxation=False,
            shape_cells=grid.shape_cells,
            verb=4,
            maxit=5,
        )
        var.l2_refe = sl.norm(sfield.field, check_finite=False)

        # Call krylov and ensure it fails properly.
        solver.krylov(vmodel, sfield, efield, var)
        out, _ = capsys.readouterr()
        assert 'DIVERGED' in out
Пример #5
0
    def test_bicgstab_error(self, capsys):
        # Load any case.
        dat = REGRES['res']
        model = emg3d.Model(**dat['input_model'])
        grid = model.grid
        model.property_x *= 100000  # Set stupid input to make bicgstab fail.
        model.property_y /= 100000  # Set stupid input to make bicgstab fail.
        sfield = emg3d.get_source_field(**dat['input_source'])
        vmodel = emg3d.models.VolumeModel(model, sfield)
        efield = emg3d.Field(grid)  # Initiate e-field.

        # Get var-instance
        var = solver.MGParameters(
            cycle=None,
            sslsolver=True,
            semicoarsening=False,
            linerelaxation=False,
            shape_cells=grid.shape_cells,
            verb=3,
            maxit=-1,
        )
        var.l2_refe = sl.norm(sfield.field, check_finite=False)

        # Call krylov and ensure it fails properly.
        solver.krylov(vmodel, sfield, efield, var)
        out, _ = capsys.readouterr()
        assert '* ERROR   :: Error in bicgstab' in out
Пример #6
0
    def test_basic(self, capsys):
        # This should reach every line of solver.multigrid.
        dat = REGRES['res']
        model = emg3d.Model(**dat['input_model'])
        grid = model.grid
        sfield = emg3d.get_source_field(**dat['input_source'])
        vmodel = emg3d.models.VolumeModel(model, sfield)
        efield = emg3d.Field(grid)  # Initiate e-field.

        # Get var-instance
        var = solver.MGParameters(
            cycle='F',
            sslsolver=False,
            semicoarsening=True,
            linerelaxation=True,
            shape_cells=grid.shape_cells,
            verb=5,
            nu_init=2,
            maxit=-1,
        )
        var.l2_refe = sl.norm(sfield.field, check_finite=False)

        # Call multigrid.
        solver.multigrid(vmodel, sfield, efield, var)
        out, _ = capsys.readouterr()
        assert '> CONVERGED' in out
Пример #7
0
    def test_laplace(self, ):
        # Regression test for homogeneous halfspace in Laplace domain.
        # Not very sophisticated; replace/extend by more detailed tests.
        dat = REGRES['lap']

        model = emg3d.Model(**dat['input_model'])
        grid = model.grid
        sfield = emg3d.get_source_field(**dat['input_source'])

        # F-cycle
        efield = solver.solve(model, sfield, plain=True)

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['Fresult'].field, efield.field, atol=1e-14)

        # BiCGSTAB with some print checking.
        efield = solver.solve(model,
                              sfield,
                              semicoarsening=False,
                              linerelaxation=False)

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['bicresult'].field, efield.field, atol=1e-14)

        # If efield is complex, assert it fails.
        efield = emg3d.Field(grid, dtype=np.complex128)

        with pytest.raises(ValueError, match='Source field and electric fiel'):
            efield = solver.solve(model, sfield, plain=True, efield=efield)
Пример #8
0
    def test_log(self, capsys):
        dat = REGRES['res']

        model = emg3d.Model(**dat['input_model'])
        sfield = emg3d.get_source_field(**dat['input_source'])
        inp = {'model': model, 'sfield': sfield, 'plain': True, 'maxit': 1}

        efield, info = solver.solve(return_info=True, log=-1, verb=3, **inp)
        out, _ = capsys.readouterr()
        assert out == ""
        assert ' emg3d START ::' in info['log']

        efield = solver.solve(return_info=True, log=0, verb=3, **inp)
        out, _ = capsys.readouterr()
        assert ' emg3d START ::' in out

        efield, info = solver.solve(return_info=True, log=1, verb=3, **inp)
        out, _ = capsys.readouterr()
        assert ' emg3d START ::' in out
        assert ' emg3d START ::' in info['log']

        efield, info = solver.solve(return_info=True, log=1, verb=1, **inp)
        out, _ = capsys.readouterr()
        assert 'MAX. ITERATION REACHED, NOT CONVERGED' in out
        assert 'MAX. ITERATION REACHED, NOT CONVERGED' in info['log']
Пример #9
0
    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')
Пример #10
0
    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')
Пример #11
0
def test_solve_source():
    dat = REGRES['res']
    model = emg3d.Model(**dat['input_model'])
    efield = solver.solve_source(model=model,
                                 source=dat['input_source']['source'],
                                 frequency=dat['input_source']['frequency'],
                                 plain=True)
    assert_allclose(dat['Fresult'].field, efield.field)
Пример #12
0
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)
Пример #13
0
    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)
Пример #14
0
    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)
Пример #15
0
def test_reciprocity():
    frequency = 1
    center = (1_000, 10_000, 100_000)
    grid = emg3d.construct_mesh(
        center=center,
        frequency=frequency,
        properties=frequency,
        distance=[-400, 800],
    )

    # Random model parameters
    model = emg3d.Model(grid, (np.random.rand(grid.n_cells) + 1) * 10)
    c = (0, 0, 0, 0, 0)

    # Random angles
    azm0, azm1 = np.random.randint(91), np.random.randint(91)
    ele0, ele1 = np.random.randint(91), np.random.randint(91)

    srcrec0 = [[emg3d.TxElectricPoint, emg3d.RxElectricPoint],
               [emg3d.TxMagneticPoint, emg3d.RxMagneticPoint]]
    srcrec1 = [[emg3d.RxElectricPoint, emg3d.TxElectricPoint],
               [emg3d.RxMagneticPoint, emg3d.TxMagneticPoint]]

    # print(f"   loc1  /  loc2   :   azm  /  ele   :  NMRSD (%)\n{98*'-'}")
    for loc0 in srcrec0:
        for loc1 in srcrec1:

            coo1 = (center[0] + 300, center[1] + 200, center[2] + 400, azm0,
                    ele0)
            coo2 = (center[0] + 800, center[1] + 700, center[2] + 500, azm1,
                    ele1)

            field1 = emg3d.solve_source(model=model,
                                        source=loc0[0](coo1),
                                        frequency=frequency)
            field2 = emg3d.solve_source(model=model,
                                        source=loc1[1](coo2),
                                        frequency=frequency)

            if loc1[0](c).xtype == 'magnetic':
                field1 = fields.get_magnetic_field(model, field1)
            if loc0[1](c).xtype == 'magnetic':
                field2 = fields.get_magnetic_field(model, field2)

            resp1 = field1.get_receiver(loc1[0](coo2), 'linear')[0]
            resp2 = field2.get_receiver(loc0[1](coo1), 'linear')[0]

            nrmsd = 200.0 * abs(resp1 - resp2) / (abs(resp1) + abs(resp2))
            # print(f" {str(loc0[0])[25:28]}-{str(loc1[0])[25:28]} /"
            #       f" {str(loc1[1])[25:28]}-{str(loc0[1])[25:28]}"
            #       f" : {azm0:03d};{azm1:03d}/{ele0:03d};{ele1:03d}"
            #       f" : {nrmsd:6.2f}    {resp1:+.4e}; {resp2:+.4e}")

            assert nrmsd < 1.0
Пример #16
0
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)
Пример #17
0
    def test_resistivity(self):
        model = emg3d.Model(self.mesh, 1/self.values, mapping='Resistivity')

        # Forward
        forward = model.map.forward(self.values)
        assert_allclose(forward, 1/self.values)

        # Backward
        backward = model.map.backward(forward)
        assert_allclose(backward, self.values)

        # Derivative
        gradient = 2*np.ones(model.property_x.shape)
        derivative = gradient.copy()
        model.map.derivative_chain(gradient, model.property_x)
        assert_allclose(gradient, -derivative*(1/model.property_x)**2)
Пример #18
0
    def test_lgresistivity(self):
        model = emg3d.Model(self.mesh, np.log10(1/self.values),
                            mapping='LgResistivity')

        # Forward
        forward = model.map.forward(self.values)
        assert_allclose(forward, np.log10(1/self.values))

        # Backward
        backward = model.map.backward(forward)
        assert_allclose(backward, self.values)

        # Derivative
        gradient = 2*np.ones(model.property_x.shape)
        derivative = gradient.copy()
        model.map.derivative_chain(gradient, model.property_x)
        assert_allclose(gradient, -derivative*10**-model.property_x*np.log(10))
Пример #19
0
    def test_lnconductivity(self):
        model = emg3d.Model(self.mesh, np.log(self.values),
                            mapping='LnConductivity')

        # Forward
        forward = model.map.forward(self.values)
        assert_allclose(forward, np.log(self.values))

        # Backward
        backward = model.map.backward(forward)
        assert_allclose(backward, self.values)

        # Derivative
        gradient = 2*np.ones(model.property_x.shape)
        derivative = gradient.copy()
        model.map.derivative_chain(gradient, model.property_x)
        assert_allclose(gradient, derivative*np.exp(model.property_x))
Пример #20
0
def test_residual():
    # The only thing to test here is that the residual returns the same as
    # sfield-amat_x. Basically a copy of the function itself.

    # Create a grid
    src = [90, 1600, 25., 45, 45]
    grid = emg3d.TensorMesh(
        [helpers.widths(4, 2, 20, 1.2),
         np.ones(16) * 200,
         np.ones(2) * 25],
        origin=np.zeros(3))

    # 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, property_x, 0.8 * property_x, 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 an e-field
    efield = solver.solve(model, sfield, maxit=2)

    # Use directly amat_x
    rfield = sfield.copy()
    emg3d.core.amat_x(rfield.fx, rfield.fy, rfield.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])

    # Compute residual
    out = solver.residual(vmodel, sfield, efield)
    outnorm = solver.residual(vmodel, sfield, efield, True)

    # Compare
    assert_allclose(out.field, rfield.field)
    assert_allclose(outnorm, np.linalg.norm(out.field))
Пример #21
0
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
Пример #22
0
def test_expand_grid_model():
    grid = emg3d.TensorMesh([[4, 2, 2, 4], [2, 2, 2, 2], [1, 1]], (0, 0, 0))
    model = emg3d.Model(grid,
                        1,
                        np.ones(grid.shape_cells) * 2,
                        mu_r=3,
                        epsilon_r=5)

    o_model = models.expand_grid_model(model, [2, 3], 5)

    # Grid.
    assert_allclose(grid.nodes_z, o_model.grid.nodes_z[:-2])
    assert o_model.grid.nodes_z[-2] == 5
    assert o_model.grid.nodes_z[-1] == 105

    # Property x (from float).
    assert_allclose(o_model.property_x[:, :, :-2], 1)
    assert_allclose(o_model.property_x[:, :, -2], 2)
    assert_allclose(o_model.property_x[:, :, -1], 3)

    # Property y (from shape_cells).
    assert_allclose(o_model.property_y[:, :, :-2], model.property_y)
    assert_allclose(o_model.property_y[:, :, -2], 2)
    assert_allclose(o_model.property_y[:, :, -1], 3)

    # Property z.
    assert o_model.property_z is None

    # Property mu_r (from float).
    assert_allclose(o_model.mu_r[:, :, :-2], 3)
    assert_allclose(o_model.mu_r[:, :, -2], 1)
    assert_allclose(o_model.mu_r[:, :, -1], 1)

    # Property epsilon_r (from float).
    assert_allclose(o_model.epsilon_r[:, :, :-2], 5)
    assert_allclose(o_model.epsilon_r[:, :, -2], 1)
    assert_allclose(o_model.epsilon_r[:, :, -1], 1)
Пример #23
0
class TestRun:

    # Default values for run-tests
    args_dict = {
        'config': '.',
        'nproc': 1,
        'forward': False,
        'misfit': False,
        'gradient': True,
        'path': None,
        'survey': 'survey.npz',
        'model': 'model.npz',
        'output': 'output.npz',
        'save': None,
        'load': None,
        'verbosity': 0,
        'dry_run': True,
    }

    if xarray is not None:
        # Create a tiny dummy survey.
        data = np.ones((1, 17, 1))
        data[0, 8:11, 0] = np.nan
        sources = emg3d.TxElectricDipole((4125, 4000, 4000, 0, 0))
        receivers = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.RxElectricPoint,
            (np.arange(17) * 250 + 2000, 4000, 3950, 0, 0))
        survey = emg3d.Survey(
            name='CLI Survey',
            sources=sources,
            receivers=receivers,
            frequencies=1,
            noise_floor=1e-15,
            relative_error=0.05,
            data=data,
        )

    # Create a dummy grid and model.
    xx = np.ones(16) * 500
    grid = emg3d.TensorMesh([xx, xx, xx], origin=np.array([0, 0, 0]))
    model = emg3d.Model(grid, 1.)

    def test_basic(self, tmpdir, capsys):

        # Store survey and model.
        self.survey.to_file(os.path.join(tmpdir, 'survey.npz'), verb=0)
        emg3d.save(os.path.join(tmpdir, 'model.npz'),
                   model=self.model,
                   mesh=self.grid,
                   verb=0)

        args_dict = self.args_dict.copy()
        args_dict['path'] = tmpdir
        args_dict['verbosity'] = -1
        cli.run.simulation(args_dict)

        args_dict = self.args_dict.copy()
        args_dict['path'] = tmpdir
        args_dict['config'] = 'bla'
        args_dict['verbosity'] = 2
        _, _ = capsys.readouterr()

        with pytest.raises(SystemExit) as e:
            cli.run.simulation(args_dict)
        assert e.type == SystemExit
        assert "* ERROR   :: Config file not found: " in e.value.code

        # Missing survey.
        args_dict = self.args_dict.copy()
        args_dict['path'] = tmpdir
        args_dict['survey'] = 'wrong'
        with pytest.raises(SystemExit) as e:
            cli.run.simulation(args_dict)
        assert e.type == SystemExit
        assert "* ERROR   :: Survey file not found: " in e.value.code
        assert "wrong" in e.value.code

        # Missing model.
        args_dict = self.args_dict.copy()
        args_dict['path'] = tmpdir
        args_dict['model'] = 'phantommodel'
        with pytest.raises(SystemExit) as e:
            cli.run.simulation(args_dict)
        assert e.type == SystemExit
        assert "* ERROR   :: Model file not found: " in e.value.code
        assert "phantommodel" in e.value.code

        # Missing output directory.
        args_dict = self.args_dict.copy()
        args_dict['path'] = tmpdir
        args_dict['output'] = join('phantom', 'output', 'dir.npz')
        args_dict['save'] = join('phantom', 'simulation', 'save.npz')
        with pytest.raises(SystemExit) as e:
            cli.run.simulation(args_dict)
        assert e.type == SystemExit
        assert "* ERROR   :: Output directory does not exist: " in e.value.code
        assert join("phantom", "output") in e.value.code
        assert join("phantom", "simulation") in e.value.code

    def test_run(self, tmpdir, capsys):

        # Write a config file.
        config = os.path.join(tmpdir, 'emg3d.cfg')
        with open(config, 'w') as f:
            f.write("[files]\n")
            f.write("save=mysim.npz\n")
            f.write("[solver_opts]\n")
            f.write("sslsolver=False\n")
            f.write("semicoarsening=False\n")
            f.write("linerelaxation=False\n")
            f.write("maxit=1\n")

        # Store survey and model.
        self.survey.to_file(os.path.join(tmpdir, 'survey.npz'), verb=1)
        emg3d.save(os.path.join(tmpdir, 'model.npz'),
                   model=self.model,
                   mesh=self.grid,
                   verb=1)

        # Run a dry run (to output.npz).
        args_dict = self.args_dict.copy()
        args_dict['config'] = os.path.join(tmpdir, 'emg3d.cfg')
        args_dict['path'] = tmpdir
        cli.run.simulation(args_dict)

        # Actually run one iteration (to output2.npz).
        args_dict = self.args_dict.copy()
        args_dict['config'] = os.path.join(tmpdir, 'emg3d.cfg')
        args_dict['path'] = tmpdir
        args_dict['dry_run'] = False
        args_dict['output'] = 'output2.npz'
        cli.run.simulation(args_dict)

        # Ensure dry_run returns same shaped data as the real thing.
        res1 = emg3d.load(os.path.join(tmpdir, 'output.npz'))
        res2 = emg3d.load(os.path.join(tmpdir, 'output2.npz'))
        assert_allclose(res1['data'].shape, res2['data'].shape)
        assert_allclose(res1['misfit'].shape, res2['misfit'].shape)
        assert_allclose(res1['gradient'].shape, res2['gradient'].shape)
        # Assert we can load the simulation
        emg3d.Simulation.from_file(os.path.join(tmpdir, 'mysim.npz'))
        assert res1['n_observations'] == np.isfinite(self.data).sum()
        assert res2['n_observations'] == np.isfinite(self.data).sum()

        # Actually run one iteration (to output2.npz).
        args_dict = self.args_dict.copy()
        args_dict['config'] = os.path.join(tmpdir, 'emg3d.cfg')
        args_dict['path'] = tmpdir
        args_dict['forward'] = True
        args_dict['gradient'] = False
        args_dict['dry_run'] = False
        args_dict['output'] = 'output3.npz'
        cli.run.simulation(args_dict)
        res3 = emg3d.load(os.path.join(tmpdir, 'output3.npz'))
        assert 'misfit' not in res3
        assert 'gradient' not in res3

        # Redo for misfit, loading existing simulation.
        args_dict = self.args_dict.copy()
        args_dict['config'] = os.path.join(tmpdir, 'emg3d.cfg')
        args_dict['path'] = tmpdir
        args_dict['forward'] = False
        args_dict['misfit'] = True
        args_dict['gradient'] = False
        args_dict['dry_run'] = False
        args_dict['load'] = 'mysim.npz'
        args_dict['output'] = 'output3.npz'
        cli.run.simulation(args_dict)
        res3 = emg3d.load(os.path.join(tmpdir, 'output3.npz'))
        assert 'misfit' in res3
        assert 'gradient' not in res3

    def test_data(self, tmpdir, capsys):

        # Write a config file; remove_empty=False (default)
        config = os.path.join(tmpdir, 'emg3d.cfg')
        with open(config, 'w') as f:
            f.write("[data]\n")
            f.write("sources=TxED-1\n")
            f.write("receivers=RxEP-05, RxEP-10, RxEP-02, RxEP-12, RxEP-06\n")
            f.write("frequencies=f-1")

        # Store survey and model.
        self.survey.to_file(os.path.join(tmpdir, 'survey.npz'), verb=1)
        emg3d.save(os.path.join(tmpdir, 'model.npz'),
                   model=self.model,
                   mesh=self.grid,
                   verb=1)

        # Run a dry run (to output.npz).
        args_dict = self.args_dict.copy()
        args_dict['config'] = os.path.join(tmpdir, 'emg3d.cfg')
        args_dict['path'] = tmpdir
        cli.run.simulation(args_dict.copy())

        # Ensure dry_run returns same shaped data as the real thing.
        res = emg3d.load(os.path.join(tmpdir, 'output.npz'))
        assert_allclose(res['data'].shape, (1, 5, 1))
        assert res['n_observations'] == 4

        # Append config file with: remove_empty=True
        with open(config, 'a') as f:
            f.write("\nremove_empty=True")

        # Run a dry run (to output.npz).
        cli.run.simulation(args_dict)

        # Ensure dry_run returns same shaped data as the real thing.
        res = emg3d.load(os.path.join(tmpdir, 'output.npz'))
        assert_allclose(res['data'].shape, (1, 4, 1))
        assert res['n_observations'] == 4
Пример #24
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,
        )
Пример #25
0
    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,
        ]])
Пример #26
0
    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
Пример #27
0
    def test_simulation_automatic(self, capsys):
        # Create a simple survey
        sources = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.TxElectricDipole, (0, [1000, 3000, 5000], -950, 0, 0))
        receivers = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.RxElectricPoint,
            ([-3000, 0, 3000], [0, 3000, 6000], -1000, 0, 0))
        frequencies = (0.1, 1.0, 10.0)

        survey = emg3d.Survey(sources,
                              receivers,
                              frequencies,
                              name='Test',
                              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(4) * 500], np.array([-1250, -1250, -2250]))
        model = emg3d.Model(grid, 1)

        # Create a simulation, compute all fields.
        inp = {
            'survey': survey,
            'model': model,
            'gridding_opts': {
                'expand': [1, 0.5],
                'seasurface': 0,
                'verb': 1
            }
        }
        b_sim = simulations.Simulation(name='both', gridding='both', **inp)
        f_sim = simulations.Simulation(name='freq',
                                       gridding='frequency',
                                       **inp)
        t_sim = simulations.Simulation(name='src', gridding='source', **inp)
        s_sim = simulations.Simulation(name='single', gridding='single', **inp)

        # Quick repr test.
        assert " 24 x 24 (13,824) - 160 x 160 x 96 (2,457," in b_sim.__repr__()
        assert " 24 x 24 (13,824) - 160 x 160 x 96 (2,457," in f_sim.__repr__()
        assert "Source-dependent grids; 64 x 64 x 40 (163," in t_sim.__repr__()
        assert "ources and frequencies; 64 x 64 x 40 (163," in s_sim.__repr__()

        # Quick print_grid test:
        _, _ = capsys.readouterr()  # empty
        b_sim.print_grid_info()
        out, _ = capsys.readouterr()
        assert "= Source: TxED-1; Frequency: 10.0 Hz =" in out
        assert "== GRIDDING IN X ==" in out
        assert b_sim.get_grid('TxED-1', 1.0).__repr__() in out

        _, _ = capsys.readouterr()  # empty
        out = f_sim.print_grid_info(return_info=True)
        out2, _ = capsys.readouterr()
        assert out2 == ""
        assert "= Source: all" in out
        assert "== GRIDDING IN X ==" in out
        assert f_sim.get_grid('TxED-3', 1.0).__repr__() in out

        t_sim.print_grid_info()
        out, _ = capsys.readouterr()
        assert "; Frequency: all" in out
        assert "== GRIDDING IN X ==" in out
        assert t_sim.get_grid('TxED-1', 10.0).__repr__() in out

        _, _ = capsys.readouterr()  # empty
        out = s_sim.print_grid_info(return_info=True)
        out2, _ = capsys.readouterr()
        assert out2 == ""
        assert "= Source: all; Frequency: all =" in out
        assert "== GRIDDING IN X ==" in out
        assert s_sim.get_grid('TxED-3', 0.1).__repr__() in out

        assert s_sim.print_grid_info(verb=-1) is None

        # Grids: Middle source / middle frequency should be the same in all.
        assert f_sim.get_grid('TxED-2', 1.0) == t_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_grid('TxED-2', 1.0) == s_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_grid('TxED-2', 1.0) == b_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == t_sim.get_model('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == s_sim.get_model('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == b_sim.get_model('TxED-2', 1.0)

        # Copy:
        f_sim_copy = f_sim.copy()
        assert (f_sim.get_grid('TxED-1',
                               1.0) == f_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in f_sim.gridding_opts.keys()
        assert 'expand' not in f_sim_copy.gridding_opts.keys()
        s_sim_copy = s_sim.copy()
        assert (s_sim.get_grid('TxED-1',
                               1.0) == s_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in s_sim.gridding_opts.keys()
        assert 'expand' not in s_sim_copy.gridding_opts.keys()
        t_sim_copy = t_sim.copy()
        assert (t_sim.get_grid('TxED-1',
                               1.0) == t_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in t_sim.gridding_opts.keys()
        assert 'expand' not in t_sim_copy.gridding_opts.keys()
Пример #28
0
class TestSimulation():
    if xarray is not None:
        # Create a simple survey

        # Sources: 1 Electric Dipole, 1 Magnetic Dipole, 1 Electric Wire.
        s1 = emg3d.TxElectricDipole((0, 1000, -950, 0, 0))
        s2 = emg3d.TxMagneticDipole((0, 3000, -950, 90, 0))
        s3 = emg3d.TxElectricWire(([0, 4900, -950], [-20, 5000,
                                                     -950], [20, 5100, -950]))
        sources = emg3d.surveys.txrx_lists_to_dict([s1, s2, s3])

        # Receivers: 1 Electric Point, 1 Magnetic Point
        e_rec = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.RxElectricPoint, (np.arange(6) * 1000, 0, -1000, 0, 0))
        m_rec = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.RxMagneticPoint, (np.arange(6) * 1000, 0, -1000, 90, 0))
        receivers = emg3d.surveys.txrx_lists_to_dict([e_rec, m_rec])

        # Frequencies
        frequencies = (1.0, 2.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,
                                                'sslsolver': False,
                                                'linerelaxation': False,
                                                'semicoarsening': False
                                            },
                                            gridding='same')

        # Do first one single and then all together.
        simulation.get_efield('TxED-1', 'f-1')
        simulation.compute(observed=True, min_offset=1100)

    def test_same(self):
        assert self.simulation.get_model('TxMD-2', 'f-1') == self.model
        assert self.simulation.get_grid('TxEW-3', 1.0) == self.grid

    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

    def test_responses(self):
        # Check min_offset were switched-off
        assert_allclose(self.simulation.data.observed[0, 0, 0].data, np.nan)
        assert_allclose(self.simulation.data.observed[0, 6, 0].data, np.nan)

        # Get efield responses
        e_resp = self.simulation.get_efield('TxMD-2', 1.0).get_receiver(
            self.survey.receivers.values())
        assert_allclose(self.simulation.data.synthetic[1, :6, 0].data,
                        e_resp[:6],
                        atol=1e-16)

        # Get hfield responses
        m_resp = self.simulation.get_hfield('TxMD-2', 1.0).get_receiver(
            self.survey.receivers.values())
        assert_allclose(self.simulation.data.synthetic[1, 6:, 0].data,
                        m_resp[6:],
                        atol=1e-16)

    def test_errors(self):
        with pytest.raises(TypeError, match='Unexpected '):
            simulations.Simulation(self.survey,
                                   self.model,
                                   unknown=True,
                                   name='Test2')

        # gridding='same' with gridding_opts.
        with pytest.raises(TypeError, match="`gridding_opts` is not permitt"):
            simulations.Simulation(self.survey,
                                   self.model,
                                   name='Test',
                                   gridding='same',
                                   gridding_opts={'bummer': True})

        # expand without seasurface
        with pytest.raises(KeyError, match="is required if"):
            simulations.Simulation(self.survey,
                                   self.model,
                                   name='Test',
                                   gridding='single',
                                   gridding_opts={'expand': [1, 2]})

    def test_reprs(self):
        test = self.simulation.__repr__()

        assert "Simulation «TestSim»" in test
        assert "Survey «TestSurv»: 3 sources; 12 receivers; 2 frequenc" in test
        assert "Model: resistivity; isotropic; 32 x 16 x 16 (8,192)" in test
        assert "Gridding: Same grid as for model" in test

        test = self.simulation._repr_html_()
        assert "Simulation «TestSim»" in test
        assert "Survey «TestSurv»:    3 sources;    12 receivers;    2" in test
        assert "Model: resistivity; isotropic; 32 x 16 x 16 (8,192)" in test
        assert "Gridding: Same grid as for model" in test

    def test_copy(self, tmpdir):
        with pytest.raises(TypeError, match="Unrecognized `what`: nothing"):
            self.simulation.copy('nothing')

        sim2 = self.simulation.copy()
        assert self.simulation.name == sim2.name
        assert self.simulation.survey.sources == sim2.survey.sources
        assert_allclose(
            self.simulation.get_efield('TxED-1', 1.0).field,
            sim2.get_efield('TxED-1', 1.0).field)

        # Also check to_file()/from_file().
        sim_dict = self.simulation.to_dict('all')
        sim2 = simulations.Simulation.from_dict(sim_dict.copy())
        assert self.simulation.name == sim2.name
        assert self.simulation.survey.name == sim2.survey.name
        assert self.simulation.max_workers == sim2.max_workers
        assert self.simulation.gridding == sim2.gridding
        assert self.simulation.model == sim2.model

        del sim_dict['survey']
        with pytest.raises(KeyError, match="'survey'"):
            simulations.Simulation.from_dict(sim_dict)

        # Also check to_file()/from_file().
        self.simulation.to_file(tmpdir + '/test.npz', what='all')
        sim2 = simulations.Simulation.from_file(tmpdir + '/test.npz')
        assert self.simulation.name == sim2.name
        assert self.simulation.survey.name == sim2.survey.name
        assert self.simulation.max_workers == sim2.max_workers
        assert self.simulation.gridding == sim2.gridding
        assert self.simulation.model == sim2.model

        sim9 = simulations.Simulation.from_file(tmpdir + '/test.npz', verb=-1)
        assert sim2.name == sim9[0].name
        assert 'Data loaded from' in sim9[1]

        # Clean and ensure it is empty
        sim3 = self.simulation.copy()
        sim3.clean('all')
        assert sim3._dict_efield['TxMD-2']['f-1'] is None
        assert sim3._dict_efield_info['TxMD-2']['f-1'] is None
        with pytest.raises(TypeError, match="Unrecognized `what`: nothing"):
            sim3.clean('nothing')

    def test_dicts_provided(self):
        grids = self.simulation._dict_grid.copy()

        # dict
        sim1 = simulations.Simulation(self.survey,
                                      self.model,
                                      gridding='dict',
                                      gridding_opts=grids,
                                      name='Test2')
        m1 = sim1.get_model('TxEW-3', 1.0)
        g1 = sim1.get_grid('TxEW-3', 1.0)

        # provide
        sim2 = simulations.Simulation(self.survey,
                                      self.model,
                                      name='Test2',
                                      gridding='input',
                                      gridding_opts=grids['TxEW-3']['f-1'])
        m2 = sim2.get_model('TxEW-3', 1.0)
        g2 = sim2.get_grid('TxEW-3', 1.0)

        assert m1 == m2
        assert g1 == g2

        # to/from_dict
        sim1copy = sim1.copy()
        sim2copy = sim2.copy()
        m1c = sim1copy.get_model('TxEW-3', 1.0)
        g1c = sim1copy.get_grid('TxEW-3', 1.0)
        m2c = sim2copy.get_model('TxEW-3', 1.0)
        g2c = sim2copy.get_grid('TxEW-3', 1.0)
        assert m1 == m1c
        assert g1 == g1c
        assert m2 == m2c
        assert g2 == g2c

    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_synthetic(self):
        sim = self.simulation.copy()
        sim._dict_efield = sim._dict_initiate  # Reset
        sim.compute(observed=True, add_noise=False)
        assert_allclose(sim.data.synthetic, sim.data.observed)
        assert sim.survey.size == sim.data.observed.size

    def test_input_gradient(self):
        # Create another mesh, so there will be a difference.
        newgrid = emg3d.TensorMesh(
            [np.ones(16) * 500,
             np.ones(8) * 1000,
             np.ones(8) * 1000], np.array([-1250, -1250, -2250]))

        simulation = simulations.Simulation(self.survey,
                                            self.model,
                                            max_workers=1,
                                            solver_opts={
                                                'maxit': 1,
                                                'verb': 0,
                                                'sslsolver': False,
                                                'linerelaxation': False,
                                                'semicoarsening': False
                                            },
                                            gridding='input',
                                            gridding_opts=newgrid,
                                            name='TestX')

        with pytest.warns(UserWarning, match='Receiver responses were obtain'):
            grad = simulation.gradient

        with pytest.warns(UserWarning, match='Receiver responses were obtain'):
            vec = simulation.data.residual.data.copy()
            vec *= simulation.data.weights.data
            jtvec = simulation.jtvec(vec)
        assert_allclose(grad, jtvec)

        jvec = simulation.jvec(np.ones(newgrid.n_cells))
        assert jvec.shape == simulation.data.observed.data.shape

        # Ensure the gradient has the shape of the model, not of the input.
        assert grad.shape == self.model.shape

        sim2 = simulation.to_dict(what='all', copy=True)
        sim3 = simulation.to_dict(what='plain', copy=True)
        assert 'residual' in sim2['survey']['data'].keys()
        assert 'residual' not in sim3['survey']['data'].keys()

        simulation.clean('all')  # Should remove 'residual', 'bfield-dicts'
        sim5 = simulation.to_dict('all')
        assert 'residual' not in sim5['survey']['data'].keys()
        assert '_dict_bfield' not in sim5.keys()

    def test_simulation_automatic(self, capsys):
        # Create a simple survey
        sources = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.TxElectricDipole, (0, [1000, 3000, 5000], -950, 0, 0))
        receivers = emg3d.surveys.txrx_coordinates_to_dict(
            emg3d.RxElectricPoint,
            ([-3000, 0, 3000], [0, 3000, 6000], -1000, 0, 0))
        frequencies = (0.1, 1.0, 10.0)

        survey = emg3d.Survey(sources,
                              receivers,
                              frequencies,
                              name='Test',
                              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(4) * 500], np.array([-1250, -1250, -2250]))
        model = emg3d.Model(grid, 1)

        # Create a simulation, compute all fields.
        inp = {
            'survey': survey,
            'model': model,
            'gridding_opts': {
                'expand': [1, 0.5],
                'seasurface': 0,
                'verb': 1
            }
        }
        b_sim = simulations.Simulation(name='both', gridding='both', **inp)
        f_sim = simulations.Simulation(name='freq',
                                       gridding='frequency',
                                       **inp)
        t_sim = simulations.Simulation(name='src', gridding='source', **inp)
        s_sim = simulations.Simulation(name='single', gridding='single', **inp)

        # Quick repr test.
        assert " 24 x 24 (13,824) - 160 x 160 x 96 (2,457," in b_sim.__repr__()
        assert " 24 x 24 (13,824) - 160 x 160 x 96 (2,457," in f_sim.__repr__()
        assert "Source-dependent grids; 64 x 64 x 40 (163," in t_sim.__repr__()
        assert "ources and frequencies; 64 x 64 x 40 (163," in s_sim.__repr__()

        # Quick print_grid test:
        _, _ = capsys.readouterr()  # empty
        b_sim.print_grid_info()
        out, _ = capsys.readouterr()
        assert "= Source: TxED-1; Frequency: 10.0 Hz =" in out
        assert "== GRIDDING IN X ==" in out
        assert b_sim.get_grid('TxED-1', 1.0).__repr__() in out

        _, _ = capsys.readouterr()  # empty
        out = f_sim.print_grid_info(return_info=True)
        out2, _ = capsys.readouterr()
        assert out2 == ""
        assert "= Source: all" in out
        assert "== GRIDDING IN X ==" in out
        assert f_sim.get_grid('TxED-3', 1.0).__repr__() in out

        t_sim.print_grid_info()
        out, _ = capsys.readouterr()
        assert "; Frequency: all" in out
        assert "== GRIDDING IN X ==" in out
        assert t_sim.get_grid('TxED-1', 10.0).__repr__() in out

        _, _ = capsys.readouterr()  # empty
        out = s_sim.print_grid_info(return_info=True)
        out2, _ = capsys.readouterr()
        assert out2 == ""
        assert "= Source: all; Frequency: all =" in out
        assert "== GRIDDING IN X ==" in out
        assert s_sim.get_grid('TxED-3', 0.1).__repr__() in out

        assert s_sim.print_grid_info(verb=-1) is None

        # Grids: Middle source / middle frequency should be the same in all.
        assert f_sim.get_grid('TxED-2', 1.0) == t_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_grid('TxED-2', 1.0) == s_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_grid('TxED-2', 1.0) == b_sim.get_grid('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == t_sim.get_model('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == s_sim.get_model('TxED-2', 1.0)
        assert f_sim.get_model('TxED-2', 1.0) == b_sim.get_model('TxED-2', 1.0)

        # Copy:
        f_sim_copy = f_sim.copy()
        assert (f_sim.get_grid('TxED-1',
                               1.0) == f_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in f_sim.gridding_opts.keys()
        assert 'expand' not in f_sim_copy.gridding_opts.keys()
        s_sim_copy = s_sim.copy()
        assert (s_sim.get_grid('TxED-1',
                               1.0) == s_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in s_sim.gridding_opts.keys()
        assert 'expand' not in s_sim_copy.gridding_opts.keys()
        t_sim_copy = t_sim.copy()
        assert (t_sim.get_grid('TxED-1',
                               1.0) == t_sim_copy.get_grid('TxED-1', 1.0))
        assert 'expand' not in t_sim.gridding_opts.keys()
        assert 'expand' not in t_sim_copy.gridding_opts.keys()

    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_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)
Пример #29
0
class TestEstimateGriddingOpts():
    if xarray is not None:
        # Create a simple survey
        sources = emg3d.surveys.txrx_coordinates_to_dict(
                emg3d.TxElectricDipole,
                (0, [1000, 3000, 5000], -950, 0, 0))
        receivers = emg3d.surveys.txrx_coordinates_to_dict(
                emg3d.RxElectricPoint,
                (np.arange(11)*500, 2000, -1000, 0, 0))
        frequencies = (0.1, 10.0)

        survey = emg3d.Survey(
                sources, receivers, frequencies, noise_floor=1e-15,
                relative_error=0.05)

        # Create a simple grid and model
        grid = meshes.TensorMesh(
                [np.ones(32)*250, np.ones(16)*500, np.ones(16)*500],
                np.array([-1250, -1250, -2250]))
        model = emg3d.Model(grid, 0.1, np.ones(grid.shape_cells)*10)
        model.property_y[5, 8, 3] = 100000  # Cell at source center

    def test_empty_dict(self):
        gdict = meshes.estimate_gridding_opts({}, self.model, self.survey)

        assert gdict['frequency'] == 1.0
        assert gdict['mapping'] == self.model.map.name
        assert_allclose(gdict['center'], (0, 3000, -950))
        assert_allclose(gdict['domain']['x'], (-500, 5500))
        assert_allclose(gdict['domain']['y'], (600, 5400))
        assert_allclose(gdict['domain']['z'], (-3651, -651))
        assert_allclose(gdict['properties'], [100000, 10, 10, 10, 10, 10, 10])

    def test_mapping_vector(self):
        gridding_opts = {
            'mapping': "LgConductivity",
            'vector': 'xZ',
            }
        gdict = meshes.estimate_gridding_opts(
                gridding_opts, self.model, self.survey)

        assert_allclose(
                gdict['properties'],
                np.log10(1/np.array([100000, 10, 10, 10, 10, 10, 10])),
                atol=1e-15)
        assert_allclose(gdict['vector']['x'], self.grid.nodes_x)
        assert gdict['vector']['y'] is None
        assert_allclose(gdict['vector']['z'], self.grid.nodes_z)

    def test_vector_domain_distance(self):
        gridding_opts = {
                'vector': 'Z',
                'domain': (None, [-1000, 1000], None),
                'distance': [[5, 10], None, None],
                }
        gdict = meshes.estimate_gridding_opts(
                gridding_opts, self.model, self.survey)

        assert gdict['vector']['x'] == gdict['vector']['y'] is None
        assert_allclose(gdict['vector']['z'], self.model.grid.nodes_z)

        assert gdict['domain']['x'] is None
        assert gdict['domain']['y'] == [-1000, 1000]
        assert gdict['domain']['z'] == [self.model.grid.nodes_z[0],
                                        self.model.grid.nodes_z[-1]]
        assert gdict['distance']['x'] == [5, 10]
        assert gdict['distance']['y'] == gdict['distance']['z'] is None

        # As dict
        gridding_opts = {
                'vector': 'Z',
                'domain': {'x': None, 'y': [-1000, 1000], 'z': None},
                'distance': {'x': [5, 10], 'y': None, 'z': None},
                }
        gdict = meshes.estimate_gridding_opts(
                gridding_opts, self.model, self.survey)

        assert gdict['vector']['x'] == gdict['vector']['y'] is None
        assert_allclose(gdict['vector']['z'], self.model.grid.nodes_z)

        assert gdict['domain']['x'] is None
        assert gdict['domain']['y'] == [-1000, 1000]
        assert gdict['domain']['z'] == [self.model.grid.nodes_z[0],
                                        self.model.grid.nodes_z[-1]]
        assert gdict['distance']['x'] == [5, 10]
        assert gdict['distance']['y'] == gdict['distance']['z'] is None

    def test_pass_along(self):
        gridding_opts = {
            'vector': {'x': None, 'y': 1, 'z': None},
            'stretching': [1.2, 1.3],
            'seasurface': -500,
            'cell_numbers': [10, 20, 30],
            'lambda_factor': 0.8,
            'max_buffer': 10000,
            'min_width_limits': ([20, 40], [20, 40], [20, 40]),
            'min_width_pps': 4,
            'verb': -1,
            }

        gdict = meshes.estimate_gridding_opts(
                gridding_opts.copy(), self.model, self.survey)

        # Check that all parameters passed unchanged.
        gdict2 = {k: gdict[k] for k, _ in gridding_opts.items()}
        # Except the tuple, which should be a dict now
        gridding_opts['min_width_limits'] = {
                'x': gridding_opts['min_width_limits'][0],
                'y': gridding_opts['min_width_limits'][1],
                'z': gridding_opts['min_width_limits'][2]
        }
        assert helpers.compare_dicts(gdict2, gridding_opts)

    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_error(self):
        with pytest.raises(TypeError, match='Unexpected gridding_opts'):
            _ = meshes.estimate_gridding_opts(
                    {'what': True}, self.model, self.survey)
Пример #30
0
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