Ejemplo n.º 1
0
    def prob(self):
        if getattr(self, '_prob', None) is None:
            self._prob = getattr(
                TDEM, 'Problem3D_{}'.format(self.formulation)
            )(
                self.meshGenerator.mesh,
                timeSteps=self.modelParameters.timeSteps,
                sigmaMap=self.physprops.wires.sigma,
                mu=self.physprops.
                mu,  # right now the TDEM code doesn't support mu inversions
                Solver=Solver,
                verbose=self.verbose)

            self._survey = TDEM.Survey(self.srcList.srcList)

            self._prob.pair(self._survey)
        return self._prob
Ejemplo n.º 2
0
    def __init__(self, **kwargs):
        super(SimulationTDEM, self).__init__(**kwargs)

        self._prob = getattr(
                TDEM, 'Problem3D_{}'.format(self.formulation)
                )(
                self.meshGenerator.mesh,
                timeSteps=self.cp.timeSteps,
                sigmaMap=self.physprops.wires.sigma,
                mu=self.physprops.mu, # right now the TDEM code doesn't support mu inversions
                Solver=Pardiso
            )

        if getattr(self.src, "physics", None) is None:
            self.src.physics = "TDEM"

        self._survey = TDEM.Survey(self.src.srcList)

        self._prob.pair(self._survey)
Ejemplo n.º 3
0
def run_simulation(fname="tdem_gs_half.h5",
                   sigma_block=0.01,
                   sigma_halfspace=0.01):
    from SimPEG.EM import TDEM, Analytics, mu_0
    import numpy as np
    from SimPEG import Mesh, Maps, Utils, EM, Survey
    from pymatsolver import Pardiso

    cs = 20
    ncx, ncy, ncz = 20, 20, 20
    npad = 10
    hx = [(cs, npad, -1.5), (cs, ncx), (cs, npad, 1.5)]
    hy = [(cs, npad, -1.5), (cs, ncy), (cs, npad, 1.5)]
    hz = [(cs, npad, -1.5), (cs, ncz), (cs, npad, 1.5)]
    mesh = Mesh.TensorMesh([hx, hy, hz], "CCC")
    sigma = np.ones(mesh.nC) * sigma_halfspace
    blk_ind = Utils.ModelBuilder.getIndicesBlock(np.r_[-40, -40, -160],
                                                 np.r_[40, 40,
                                                       -80], mesh.gridCC)
    sigma[mesh.gridCC[:, 2] > 0.0] = 1e-8
    sigma[blk_ind] = sigma_block

    xmin, xmax = -200.0, 200.0
    ymin, ymax = -200.0, 200.0
    x = mesh.vectorCCx[np.logical_and(mesh.vectorCCx > xmin,
                                      mesh.vectorCCx < xmax)]
    y = mesh.vectorCCy[np.logical_and(mesh.vectorCCy > ymin,
                                      mesh.vectorCCy < ymax)]
    xyz = Utils.ndgrid(x, y, np.r_[-1.0])

    px = np.r_[-200.0, 200.0]
    py = np.r_[0.0, 0.0]
    pz = np.r_[0.0, 0.0]
    srcLoc = np.c_[px, py, pz]

    from scipy.interpolate import interp1d

    prb = TDEM.Problem3D_b(mesh, sigma=sigma, verbose=True)
    prb.Solver = Pardiso
    prb.solverOpts = {"is_symmetric": False}
    prb.timeSteps = [(1e-3, 10), (2e-5, 10), (1e-4, 10), (5e-4, 10),
                     (1e-3, 10)]
    t0 = 0.01 + 1e-4
    out = EM.Utils.VTEMFun(prb.times, 0.01, t0, 200)
    wavefun = interp1d(prb.times, out)
    waveform = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun)
    input_currents = wavefun(prb.times)

    times = np.logspace(-4, -2, 21)
    rx_ex = TDEM.Rx.Point_e(xyz, times + t0, orientation="x")
    rx_ey = TDEM.Rx.Point_e(xyz, times + t0, orientation="y")
    rx_by = TDEM.Rx.Point_e(xyz, times + t0, orientation="y")

    rxList = [rx_ex, rx_ey, rx_by]
    src = TDEM.Src.LineCurrent(rxList, loc=srcLoc, waveform=waveform)
    survey = TDEM.Survey([src])
    survey.pair(prb)

    f = prb.fields(sigma)

    xyzlim = np.array([[xmin, xmax], [ymin, ymax], [-400, 0.0]])
    actinds, meshCore = Utils.ExtractCoreMesh(xyzlim, mesh)
    Pex = mesh.getInterpolationMat(meshCore.gridCC, locType="Ex")
    Pey = mesh.getInterpolationMat(meshCore.gridCC, locType="Ey")
    Pez = mesh.getInterpolationMat(meshCore.gridCC, locType="Ez")
    Pfx = mesh.getInterpolationMat(meshCore.gridCC, locType="Fx")
    Pfy = mesh.getInterpolationMat(meshCore.gridCC, locType="Fy")
    Pfz = mesh.getInterpolationMat(meshCore.gridCC, locType="Fz")

    sigma_core = sigma[actinds]

    def getEBJcore(src0):
        B0 = np.r_[Pfx * f[src0, "b"], Pfy * f[src0, "b"], Pfz * f[src0, "b"]]
        E0 = np.r_[Pex * f[src0, "e"], Pey * f[src0, "e"], Pez * f[src0, "e"]]
        J0 = Utils.sdiag(np.r_[sigma_core, sigma_core, sigma_core]) * E0
        return E0, B0, J0

    E, B, J = getEBJcore(src)
    tdem_gs = {
        "E": E,
        "B": B,
        "J": J,
        "sigma": sigma_core,
        "mesh": meshCore.serialize(),
        "time": prb.times - t0,
        "input_currents": input_currents,
    }
    dd.io.save(fname, tdem_gs)
Ejemplo n.º 4
0
    [], loc=np.r_[0., 0., 0.], orientation="z", radius=100,
    waveform=quarter_sine
)

src_list_magnetostatic = [src_magnetostatic]
src_list_ramp_on = [src_ramp_on]

###############################################################################
# Create the simulations
# ----------------------
#
# To simulate magnetic flux data, we use the b-formulation of Maxwell's
# equations

prob_magnetostatic = TDEM.Problem3D_b(
    mesh=mesh, sigmaMap=Maps.IdentityMap(mesh), timeSteps=ramp,
    Solver=Pardiso
)
prob_ramp_on = TDEM.Problem3D_b(
    mesh=mesh, sigmaMap=Maps.IdentityMap(mesh), timeSteps=ramp,
    Solver=Pardiso
)

survey_magnetostatic = TDEM.Survey(srcList=src_list_magnetostatic)
survey_ramp_on = TDEM.Survey(src_list_ramp_on)

prob_magnetostatic.pair(survey_magnetostatic)
prob_ramp_on.pair(survey_ramp_on)

###############################################################################
# Run the long on-time simulation
# -------------------------------
def run(plotIt=True, saveFig=False):

    # Set up cylindrically symmeric mesh
    cs, ncx, ncz, npad = 10., 15, 25, 13  # padded cyl mesh
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')

    # Conductivity model
    layerz = np.r_[-200., -100.]
    layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1])
    active = mesh.vectorCCz < 0.
    sig_half = 1e-2  # Half-space conductivity
    sig_air = 1e-8  # Air conductivity
    sig_layer = 5e-2  # Layer conductivity
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer

    # Mapping
    actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap
    mtrue = np.log(sigma[active])

    # ----- FDEM problem & survey ----- #
    rxlocs = Utils.ndgrid([np.r_[50.], np.r_[0], np.r_[0.]])
    bzr = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real')
    bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'imag')

    freqs = np.logspace(2, 3, 5)
    srcLoc = np.array([0., 0., 0.])

    print('min skin depth = ', 500. / np.sqrt(freqs.max() * sig_half),
          'max skin depth = ', 500. / np.sqrt(freqs.min() * sig_half))
    print('max x ', mesh.vectorCCx.max(), 'min z ', mesh.vectorCCz.min(),
          'max z ', mesh.vectorCCz.max())

    srcList = [
        FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z')
        for freq in freqs
    ]

    surveyFD = FDEM.Survey(srcList)
    prbFD = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver)
    prbFD.pair(surveyFD)
    std = 0.03
    surveyFD.makeSyntheticData(mtrue, std)
    surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-5

    # FDEM inversion
    np.random.seed(1)
    dmisfit = DataMisfit.l2_DataMisfit(surveyFD)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Simple(regMesh)
    opt = Optimization.InexactGaussNewton(maxIterCG=10)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion Directives
    beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.)
    target = Directives.TargetMisfit()
    directiveList = [beta, betaest, target]

    inv = Inversion.BaseInversion(invProb, directiveList=directiveList)
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    reg.alpha_s = 5e-1
    reg.alpha_x = 1.
    prbFD.counter = opt.counter = Utils.Counter()
    opt.remember('xc')
    moptFD = inv.run(m0)

    # TDEM problem
    times = np.logspace(-4, np.log10(2e-3), 10)
    print('min diffusion distance ',
          1.28 * np.sqrt(times.min() / (sig_half * mu_0)),
          'max diffusion distance ',
          1.28 * np.sqrt(times.max() / (sig_half * mu_0)))
    rx = TDEM.Rx.Point_b(rxlocs, times, 'z')
    src = TDEM.Src.MagDipole(
        [rx],
        waveform=TDEM.Src.StepOffWaveform(),
        loc=srcLoc  # same src location as FDEM problem
    )

    surveyTD = TDEM.Survey([src])
    prbTD = TDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver)
    prbTD.timeSteps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)]
    prbTD.pair(surveyTD)

    std = 0.03
    surveyTD.makeSyntheticData(mtrue, std)
    surveyTD.std = std
    surveyTD.eps = np.linalg.norm(surveyTD.dtrue) * 1e-5

    # TDEM inversion
    dmisfit = DataMisfit.l2_DataMisfit(surveyTD)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Simple(regMesh)
    opt = Optimization.InexactGaussNewton(maxIterCG=10)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # directives
    beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.)
    target = Directives.TargetMisfit()
    directiveList = [beta, betaest, target]

    inv = Inversion.BaseInversion(invProb, directiveList=directiveList)
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    reg.alpha_s = 5e-1
    reg.alpha_x = 1.
    prbTD.counter = opt.counter = Utils.Counter()
    opt.remember('xc')
    moptTD = inv.run(m0)

    # Plot the results
    if plotIt:
        plt.figure(figsize=(10, 8))
        ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2)
        ax1 = plt.subplot2grid((2, 2), (0, 1))
        ax2 = plt.subplot2grid((2, 2), (1, 1))

        fs = 13  # fontsize
        matplotlib.rcParams['font.size'] = fs

        # Plot the model
        ax0.semilogx(sigma[active],
                     mesh.vectorCCz[active],
                     'k-',
                     lw=2,
                     label="True")
        ax0.semilogx(np.exp(moptFD),
                     mesh.vectorCCz[active],
                     'bo',
                     ms=6,
                     markeredgecolor='k',
                     markeredgewidth=0.5,
                     label="FDEM")
        ax0.semilogx(np.exp(moptTD),
                     mesh.vectorCCz[active],
                     'r*',
                     ms=10,
                     markeredgecolor='k',
                     markeredgewidth=0.5,
                     label="TDEM")
        ax0.set_ylim(-700, 0)
        ax0.set_xlim(5e-3, 1e-1)

        ax0.set_xlabel('Conductivity (S/m)', fontsize=fs)
        ax0.set_ylabel('Depth (m)', fontsize=fs)
        ax0.grid(which='both',
                 color='k',
                 alpha=0.5,
                 linestyle='-',
                 linewidth=0.2)
        ax0.legend(fontsize=fs, loc=4)

        # plot the data misfits - negative b/c we choose positive to be in the
        # direction of primary

        ax1.plot(freqs, -surveyFD.dobs[::2], 'k-', lw=2, label="Obs (real)")
        ax1.plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2, label="Obs (imag)")

        dpredFD = surveyFD.dpred(moptTD)
        ax1.loglog(freqs,
                   -dpredFD[::2],
                   'bo',
                   ms=6,
                   markeredgecolor='k',
                   markeredgewidth=0.5,
                   label="Pred (real)")
        ax1.loglog(freqs,
                   -dpredFD[1::2],
                   'b+',
                   ms=10,
                   markeredgewidth=2.,
                   label="Pred (imag)")

        ax2.loglog(times, surveyTD.dobs, 'k-', lw=2, label='Obs')
        ax2.loglog(times,
                   surveyTD.dpred(moptTD),
                   'r*',
                   ms=10,
                   markeredgecolor='k',
                   markeredgewidth=0.5,
                   label='Pred')
        ax2.set_xlim(times.min() - 1e-5, times.max() + 1e-4)

        # Labels, gridlines, etc
        ax2.grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2)
        ax1.grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2)

        ax1.set_xlabel('Frequency (Hz)', fontsize=fs)
        ax1.set_ylabel('Vertical magnetic field (-T)', fontsize=fs)

        ax2.set_xlabel('Time (s)', fontsize=fs)
        ax2.set_ylabel('Vertical magnetic field (T)', fontsize=fs)

        ax2.legend(fontsize=fs, loc=3)
        ax1.legend(fontsize=fs, loc=3)
        ax1.set_xlim(freqs.max() + 1e2, freqs.min() - 1e1)

        ax0.set_title("(a) Recovered Models", fontsize=fs)
        ax1.set_title("(b) FDEM observed vs. predicted", fontsize=fs)
        ax2.set_title("(c) TDEM observed vs. predicted", fontsize=fs)

        plt.tight_layout(pad=1.5)

        if saveFig is True:
            plt.savefig('example1.png', dpi=600)
Ejemplo n.º 6
0
    def test_permeable_sources(self):

        target_mur = self.target_mur
        target_l = self.target_l
        target_r = self.target_r
        sigma_back = self.sigma_back
        model_names = self.model_names
        mesh = self.mesh
        radius_loop = self.radius_loop

        # Assign physical properties on the mesh
        def populate_target(mur):
            mu_model = np.ones(mesh.nC)
            x_inds = mesh.gridCC[:, 0] < target_r
            z_inds = (
                (mesh.gridCC[:, 2] <= 0) & (mesh.gridCC[:, 2] >= -target_l)
            )
            mu_model[x_inds & z_inds] = mur
            return mu_0 * mu_model

        mu_dict = {
            key: populate_target(mu) for key, mu in
            zip(model_names, target_mur)
        }
        sigma = np.ones(mesh.nC) * sigma_back

        # Plot the models
        if plotIt:
            xlim = np.r_[-200, 200]  # x-limits in meters
            zlim = np.r_[-1.5*target_l, 10.]  # z-limits in meters. (z-positive up)

            fig, ax = plt.subplots(
                1, len(model_names), figsize=(6*len(model_names), 5)
            )
            if len(model_names) == 1:
                ax = [ax]

            for a, key in zip(ax, model_names):
                plt.colorbar(mesh.plotImage(
                    mu_dict[key], ax=a,
                    pcolorOpts={'norm': LogNorm()},  # plot on a log-scale
                    mirror=True
                )[0], ax=a)
                a.set_title('{}'.format(key), fontsize=13)
            #     cylMeshGen.mesh.plotGrid(ax=a, slice='theta') # uncomment to plot the mesh on top of this
                a.set_xlim(xlim)
                a.set_ylim(zlim)
            plt.tight_layout()
            plt.show()

        ramp = [
            (1e-5, 20), (1e-4, 20), (3e-4, 20), (1e-3, 20), (3e-3, 20),
            (1e-2, 20), (3e-2, 20), (1e-1, 20), (3e-1, 20), (1,  50)
        ]
        timeSteps = ramp

        time_mesh = discretize.TensorMesh([ramp])
        offTime = 10000
        waveform = TDEM.Src.QuarterSineRampOnWaveform(
            ramp_on=np.r_[1e-4, 20], ramp_off=offTime - np.r_[1e-4, 0]
        )

        if plotIt:
            wave = np.r_[[waveform.eval(t) for t in time_mesh.gridN]]
            plt.plot(time_mesh.gridN, wave)
            plt.plot(time_mesh.gridN, np.zeros(time_mesh.nN), '-|', color='k')
            plt.show()

        src_magnetostatic = TDEM.Src.CircularLoop(
            [], loc=np.r_[0., 0., 0.], orientation="z", radius=100,
        )

        src_ramp_on = TDEM.Src.CircularLoop(
            [], loc=np.r_[0., 0., 0.], orientation="z", radius=100,
            waveform=waveform
        )

        src_list = [src_magnetostatic]
        src_list_late_ontime = [src_ramp_on]

        prob = TDEM.Problem3D_b(
            mesh=mesh, timeSteps=timeSteps, sigmaMap=Maps.IdentityMap(mesh),
            Solver=Pardiso
        )
        prob_late_ontime = TDEM.Problem3D_b(
            mesh=mesh, timeSteps=timeSteps, sigmaMap=Maps.IdentityMap(mesh),
            Solver=Pardiso
        )

        survey = TDEM.Survey(srcList=src_list)
        survey_late_ontime = TDEM.Survey(src_list_late_ontime)

        prob.pair(survey)
        prob_late_ontime.pair(survey_late_ontime)

        fields_dict = {}

        for key in model_names:
            t = time.time()
            print('--- Running {} ---'.format(key))

            prob_late_ontime.mu = mu_dict[key]
            fields_dict[key] = prob_late_ontime.fields(sigma)

            print(" ... done. Elapsed time {}".format(time.time() - t))
            print('\n')

            b_magnetostatic = {}
            b_late_ontime = {}

        for key in model_names:
            prob.mu = mu_dict[key]
            prob.sigma = sigma
            b_magnetostatic[key] = src_magnetostatic.bInitial(prob)

            prob_late_ontime.mu = mu_dict[key]
            b_late_ontime[key] = utils.mkvc(
                fields_dict[key][:, 'b', -1]
            )

        if plotIt:
            fig, ax = plt.subplots(
                len(model_names), 2, figsize=(3*len(model_names), 5)
            )

            for i, key in enumerate(model_names):
                ax[i][0].semilogy(
                    np.absolute(b_magnetostatic[key]),
                    label='magnetostatic'
                )
                ax[i][0].semilogy(
                    np.absolute(b_late_ontime[key]), label='late on-time'
                )
                ax[i][0].legend()

                ax[i][1].semilogy(
                    np.absolute(b_magnetostatic[key] - b_late_ontime[key])
                )
            plt.tight_layout()
            plt.show()

        print("Testing TDEM with permeable targets")
        passed = []
        for key in model_names:
            norm_magneotstatic = np.linalg.norm(b_magnetostatic[key])
            norm_late_ontime = np.linalg.norm(b_late_ontime[key])
            norm_diff = np.linalg.norm(
                b_magnetostatic[key] - b_late_ontime[key]
            )
            passed_test = (
                norm_diff / (0.5*(norm_late_ontime + norm_magneotstatic))
                < TOL
            )
            print("\n{}".format(key))
            print(
                "||magnetostatic||: {:1.2e}, "
                "||late on-time||: {:1.2e}, "
                "||difference||: {:1.2e} passed?: {}".format(
                    norm_magneotstatic, norm_late_ontime, norm_diff,
                    passed_test
                )
            )

            passed += [passed_test]

        assert all(passed)

        prob.sigma = 1e-4*np.ones(mesh.nC)
        v = utils.mkvc(np.random.rand(mesh.nE))
        w = utils.mkvc(np.random.rand(mesh.nF))
        assert(
            np.all(
                mesh.getEdgeInnerProduct(1e-4*np.ones(mesh.nC))*v ==
                prob.MeSigma*v
            )
        )

        assert(
            np.all(
                mesh.getEdgeInnerProduct(
                    1e-4*np.ones(mesh.nC), invMat=True
                )*v ==
                prob.MeSigmaI*v
            )
        )
        assert(
            np.all(
                mesh.getFaceInnerProduct(1./1e-4*np.ones(mesh.nC))*w ==
                prob.MfRho*w
            )
        )

        assert(
            np.all(
                mesh.getFaceInnerProduct(
                    1./1e-4*np.ones(mesh.nC), invMat=True
                )*w ==
                prob.MfRhoI*w
            )
        )

        prob.rho = 1./1e-3*np.ones(mesh.nC)
        v = utils.mkvc(np.random.rand(mesh.nE))
        w = utils.mkvc(np.random.rand(mesh.nF))
        assert(
            np.all(
                mesh.getEdgeInnerProduct(1e-3*np.ones(mesh.nC))*v ==
                prob.MeSigma*v
            )
        )

        assert(
            np.all(
                mesh.getEdgeInnerProduct(
                    1e-3*np.ones(mesh.nC), invMat=True
                )*v ==
                prob.MeSigmaI*v
            )
        )
        assert(
            np.all(
                mesh.getFaceInnerProduct(1./1e-3*np.ones(mesh.nC))*w ==
                prob.MfRho*w
            )
        )

        assert(
            np.all(
                mesh.getFaceInnerProduct(
                    1./1e-3*np.ones(mesh.nC), invMat=True
                )*w ==
                prob.MfRhoI*w
            )
        )
Ejemplo n.º 7
0
    def setUpClass(self):

        # mesh
        cs = 10
        npad = 4
        ncore = 5
        h = [(cs, npad, -1.5), (cs, ncore), (cs, npad, 1.5)]
        mesh = discretize.TensorMesh([h, h, h], x0="CCC")

        # source
        src_a = np.r_[-cs*2, 0., 0.]
        src_b = np.r_[cs*2, 0., 0.]

        s_e = np.zeros(mesh.nFx)
        src_inds = (
            (mesh.gridFx[:, 0] >= src_a[0]) & (mesh.gridFx[:, 0] <= src_b[0]) &
            (mesh.gridFx[:, 1] >= src_a[1]) & (mesh.gridFx[:, 1] <= src_b[1]) &
            (mesh.gridFx[:, 2] >= src_a[2]) & (mesh.gridFx[:, 2] <= src_b[2])
        )
        s_e[src_inds] = 1.
        s_e = np.hstack([s_e, np.zeros(mesh.nFy + mesh.nFz)])

        # define a model with a conductive, permeable target
        sigma0 = 1e-1
        sigma1 = 1

        mu0 = mu_0
        mu1 = 100*mu_0

        h_target = np.r_[-30, 30]
        target_inds = (
            (mesh.gridCC[:, 0] >= h_target[0]) & (mesh.gridCC[:, 0] <= h_target[1]) &
            (mesh.gridCC[:, 1] >= h_target[0]) & (mesh.gridCC[:, 1] <= h_target[1]) &
            (mesh.gridCC[:, 2] >= h_target[0]) & (mesh.gridCC[:, 2] <= h_target[1])
        )

        sigma = sigma0 * np.ones(mesh.nC)
        sigma[target_inds] = sigma1

        mu = mu0 * np.ones(mesh.nC)
        mu[target_inds] = mu1

        src = TDEM.Src.RawVec_Grounded([], s_e=s_e)

        timeSteps = [
            (1e-6, 20), (1e-5, 30), (3e-5, 30), (1e-4, 40), (3e-4, 30),
            (1e-3, 20), (1e-2, 17)
        ]
        prob = getattr(TDEM, "Problem3D_{}".format(self.prob_type))(
            mesh, timeSteps=timeSteps, mu=mu, sigmaMap=Maps.ExpMap(mesh),
            Solver=Pardiso
        )
        survey = TDEM.Survey([src])

        prob.model = sigma

        self.mesh = mesh
        self.prob = prob
        self.survey = survey
        self.src = src

        self.sigma = sigma
        self.mu = mu

        print("Testing problem {} \n\n".format(self.prob_type))