Exemplo n.º 1
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
Exemplo n.º 2
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
Exemplo n.º 3
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
Exemplo n.º 4
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)
Exemplo n.º 5
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)
Exemplo n.º 6
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']
Exemplo n.º 7
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)
Exemplo n.º 8
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)
Exemplo n.º 9
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))
Exemplo n.º 10
0
    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
Exemplo n.º 11
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
Exemplo n.º 12
0
def test_smoothing():
    # 1. The only thing to test here is that smoothing returns the same as
    #    the corresponding jitted functions. Basically a copy of the function
    #    itself.

    nu = 2

    widths = [
        np.ones(2) * 100,
        helpers.widths(10, 27, 10, 1.1),
        helpers.widths(2, 1, 50, 1.2)
    ]
    origin = [-w.sum() / 2 for w in widths]
    src = [0, -10, -10, 43, 13]

    # Loop and move the 2-cell dimension (100, 2) from x to y to z.
    for xyz in range(3):

        # Create a grid
        grid = emg3d.TensorMesh(
            [widths[xyz % 3], widths[(xyz + 1) % 3], widths[(xyz + 2) % 3]],
            origin=np.array([
                origin[xyz % 3], origin[(xyz + 1) % 3], origin[(xyz + 2) % 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
        field = solver.solve(model, sfield, maxit=2)

        # Collect Gauss-Seidel input (same for all routines)
        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)

        func = ['', '_x', '_y', '_z']
        for lr_dir in range(8):
            # Get it directly from core
            efield = emg3d.Field(grid, field.field)
            finp = (efield.fx, efield.fy, efield.fz)
            if lr_dir < 4:
                getattr(emg3d.core,
                        'gauss_seidel' + func[lr_dir])(efield.fx, efield.fy,
                                                       efield.fz, *inp)
            elif lr_dir == 4:
                emg3d.core.gauss_seidel_y(*finp, *inp)
                emg3d.core.gauss_seidel_z(*finp, *inp)
            elif lr_dir == 5:
                emg3d.core.gauss_seidel_x(*finp, *inp)
                emg3d.core.gauss_seidel_z(*finp, *inp)
            elif lr_dir == 6:
                emg3d.core.gauss_seidel_x(*finp, *inp)
                emg3d.core.gauss_seidel_y(*finp, *inp)
            elif lr_dir == 7:
                emg3d.core.gauss_seidel_x(*finp, *inp)
                emg3d.core.gauss_seidel_y(*finp, *inp)
                emg3d.core.gauss_seidel_z(*finp, *inp)

            # Use solver.smoothing
            ofield = emg3d.Field(grid, field.field)
            solver.smoothing(vmodel, sfield, ofield, nu, lr_dir)

            # Compare
            assert efield == ofield
Exemplo n.º 13
0
    def test_homogeneous(self, capsys):
        # Regression test for homogeneous halfspace.
        dat = REGRES['res']

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

        # F-cycle
        efield = solver.solve(model=model, sfield=sfield, plain=True, verb=4)
        out, _ = capsys.readouterr()

        assert ' emg3d START ::' in out
        assert ' [hh:mm:ss] ' in out
        assert ' MG cycles ' in out
        assert ' Final rel. error ' in out
        assert ' emg3d END   :: ' in out

        # Experimental:
        # Check if norms are also the same, at least for first two cycles.
        assert "3.399e-02  after   1 F-cycles   [1.830e-07, 0.034]   0 " in out
        assert "3.535e-03  after   2 F-cycles   [1.903e-08, 0.104]   0 " in out

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['Fresult'].field, efield.field)

        # W-cycle
        wfield = solver.solve(model, sfield, plain=True, cycle='W')

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['Wresult'].field, wfield.field)

        # V-cycle
        vfield = solver.solve(model, sfield, plain=True, cycle='V')
        _, _ = capsys.readouterr()  # clear output

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['Vresult'].field, vfield.field)

        # BiCGSTAB with some print checking.
        efield = solver.solve(model,
                              sfield,
                              verb=4,
                              sslsolver='bicgstab',
                              plain=True)
        out, _ = capsys.readouterr()
        assert ' emg3d START ::' in out
        assert ' [hh:mm:ss] ' in out
        assert ' CONVERGED' in out
        assert ' Solver steps ' in out
        assert ' MG prec. steps ' in out
        assert ' Final rel. error ' in out
        assert ' emg3d END   :: ' in out

        # Check all fields (ex, ey, and ez)
        assert_allclose(dat['bicresult'].field, efield.field)

        # Same as previous, without BiCGSTAB, but some print checking.
        efield = solver.solve(model, sfield, plain=True, verb=4)
        out, _ = capsys.readouterr()
        assert ' emg3d START ::' in out
        assert ' [hh:mm:ss] ' in out
        assert ' CONVERGED' in out
        assert ' MG cycles ' in out
        assert ' Final rel. error ' in out
        assert ' emg3d END   :: ' in out

        # Max it
        maxit = 2
        _, info = solver.solve(model,
                               sfield,
                               plain=True,
                               verb=3,
                               maxit=maxit,
                               return_info=True)
        out, _ = capsys.readouterr()
        assert ' MAX. ITERATION REACHED' in out
        assert maxit == info['it_mg']
        assert info['exit'] == 1
        assert 'MAX. ITERATION REACHED' in info['exit_message']

        # BiCGSTAB with lower verbosity, print checking.
        _ = solver.solve(model,
                         sfield,
                         sslsolver='bicgstab',
                         plain=True,
                         verb=3,
                         maxit=1)
        out, _ = capsys.readouterr()
        assert ' MAX. ITERATION REACHED' in out

        # Just check if it runs without failing for other solvers.
        _ = solver.solve(model,
                         sfield,
                         sslsolver='gcrotmk',
                         plain=True,
                         verb=5,
                         maxit=1)

        # Provide initial field.
        _, _ = capsys.readouterr()  # empty
        efield_copy = efield.copy()
        outarray = solver.solve(model,
                                sfield,
                                plain=True,
                                efield=efield_copy,
                                verb=3)
        out, _ = capsys.readouterr()

        # Ensure there is no output.
        assert outarray is None
        assert "NOTHING DONE (provided efield already good enough)" in out
        # Ensure the field did not change.
        assert_allclose(efield.field, efield_copy.field)

        # Provide initial field and return info.
        info = solver.solve(model,
                            sfield,
                            plain=True,
                            efield=efield_copy,
                            return_info=True)
        assert info['it_mg'] == 0
        assert info['it_ssl'] == 0
        assert info['exit'] == 0
        assert info['exit_message'] == 'CONVERGED'

        # Provide initial field, ensure one initial multigrid is carried out
        # without linerelaxation nor semicoarsening.
        _, _ = capsys.readouterr()  # empty
        efield = emg3d.Field(grid)
        outarray = solver.solve(model, sfield, efield=efield, maxit=2, verb=4)
        out, _ = capsys.readouterr()
        assert "after                       1 F-cycles    4 1" in out
        assert "after                       2 F-cycles    5 2" in out

        # Provide an initial source-field without frequency information.
        wrong_sfield = emg3d.Field(grid)
        wrong_sfield.field = sfield.field
        with pytest.raises(ValueError, match="Source field is missing frequ"):
            solver.solve(model,
                         wrong_sfield,
                         plain=True,
                         efield=efield,
                         verb=1)

        # Check stagnation by providing an almost zero source field.
        sfield.field = 1e-10
        _ = solver.solve(model, sfield, plain=True, maxit=100)
        out, _ = capsys.readouterr()
        assert "STAGNATED" in out

        # Check a zero field is returned for a zero source field.
        sfield.field = 0
        efield = solver.solve(model, sfield, plain=True, maxit=100, verb=3)
        out, _ = capsys.readouterr()
        assert "RETURN ZERO E-FIELD (provided sfield is zero)" in out
        assert np.linalg.norm(efield.field) == 0.0
Exemplo n.º 14
0
def test_print_one_liner(capsys):
    var = solver.MGParameters(verb=5,
                              cycle='F',
                              sslsolver=False,
                              linerelaxation=False,
                              semicoarsening=False,
                              shape_cells=(16, 8, 2))

    solver._print_one_liner(var, 1e-2, False)
    out, _ = capsys.readouterr()
    assert ":: emg3d :: 1.0e-02; 0; 0:00:0" in out

    var = solver.MGParameters(verb=5,
                              cycle='F',
                              sslsolver=True,
                              linerelaxation=False,
                              semicoarsening=False,
                              shape_cells=(16, 8, 2))
    var.exit_message = "TEST"

    solver._print_one_liner(var, 1e-2, True)
    out, _ = capsys.readouterr()
    assert ":: emg3d :: 1.0e-02; 0(0); 0:00:0" in out
    assert "TEST" in out

    grid = emg3d.TensorMesh(
        [np.ones(8), np.ones(8), np.ones(8)], origin=np.array([0, 0, 0]))
    model = emg3d.Model(grid, property_x=1.5, property_y=1.8, property_z=3.3)
    sfield = emg3d.get_source_field(grid,
                                    source=[4, 4, 4, 0, 0],
                                    frequency=10.0)

    # Dynamic one-liner.
    out, _ = capsys.readouterr()
    _ = solver.solve(model,
                     sfield,
                     sslsolver=False,
                     semicoarsening=False,
                     linerelaxation=False,
                     verb=1)
    out, _ = capsys.readouterr()
    assert '6; 0:00:' in out
    assert '; CONVERGED' in out

    out, _ = capsys.readouterr()
    _ = solver.solve(model,
                     sfield,
                     sslsolver=True,
                     semicoarsening=False,
                     linerelaxation=False,
                     verb=1)
    out, _ = capsys.readouterr()
    assert '3(5); 0:00:' in out
    assert '; CONVERGED' in out

    # One-liner.
    out, _ = capsys.readouterr()
    _ = solver.solve(model,
                     sfield,
                     sslsolver=True,
                     semicoarsening=False,
                     linerelaxation=False,
                     verb=1)
    out, _ = capsys.readouterr()
    assert '3(5); 0:00:' in out
    assert '; CONVERGED' in out