def simulate(self, srcLoc, rxLoc, time, radius=1.0):

        bz = tdem.receivers.PointMagneticFluxDensity(rxLoc,
                                                     time,
                                                     orientation="z")
        # dbzdt = EM.TDEM.Rx.Point_dbdt(rxLoc, time, orientation="z")
        src = tdem.sources.CircularLoop(
            [bz],
            waveform=tdem.sources.StepOffWaveform(),
            location=srcLoc,
            radius=radius)
        self.srcList = [src]
        survey = tdem.survey.Survey(self.srcList)

        sim = tdem.Simulation3DMagneticFluxDensity(self.mesh,
                                                   survey=survey,
                                                   sigmaMap=self.mapping)
        sim.time_steps = [
            (1e-06, 10),
            (5e-06, 10),
            (1e-05, 10),
            (5e-5, 10),
            (1e-4, 10),
            (5e-4, 10),
            (1e-3, 10),
        ]

        self.f = sim.fields(self.m)
        self.sim = sim
        dpred = sim.dpred(self.m, f=self.f)
        return dpred
def run(plotIt=True, saveFig=False):

    # Set up cylindrically symmeric mesh
    cs, ncx, ncz, npad = 10.0, 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 = discretize.CylMesh([hx, 1, hz], "00C")

    # Conductivity model
    layerz = np.r_[-200.0, -100.0]
    layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1])
    active = mesh.vectorCCz < 0.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.0], np.r_[0], np.r_[0.0]])
    bzr = FDEM.Rx.PointMagneticFluxDensitySecondary(rxlocs, "z", "real")
    bzi = FDEM.Rx.PointMagneticFluxDensitySecondary(rxlocs, "z", "imag")

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

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

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

    surveyFD = FDEM.Survey(source_list)
    prbFD = FDEM.Simulation3DMagneticFluxDensity(
        mesh, survey=surveyFD, sigmaMap=mapping, solver=Solver
    )
    rel_err = 0.03
    dataFD = prbFD.make_synthetic_data(mtrue, relative_error=rel_err, add_noise=True)
    dataFD.noise_floor = np.linalg.norm(dataFD.dclean) * 1e-5

    # FDEM inversion
    np.random.seed(1)
    dmisfit = data_misfit.L2DataMisfit(simulation=prbFD, data=dataFD)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh)
    opt = optimization.InexactGaussNewton(maxIterCG=10)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion Directives
    beta = directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1.0, seed=518936)
    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.0
    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.PointMagneticFluxDensity(rxlocs, times, "z")
    src = TDEM.Src.MagDipole(
        [rx],
        waveform=TDEM.Src.StepOffWaveform(),
        location=srcLoc,  # same src location as FDEM problem
    )

    surveyTD = TDEM.Survey([src])
    prbTD = TDEM.Simulation3DMagneticFluxDensity(
        mesh, survey=surveyTD, sigmaMap=mapping, solver=Solver
    )
    prbTD.time_steps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)]

    rel_err = 0.03
    dataTD = prbTD.make_synthetic_data(mtrue, relative_error=rel_err, add_noise=True)
    dataTD.noise_floor = np.linalg.norm(dataTD.dclean) * 1e-5

    # TDEM inversion
    dmisfit = data_misfit.L2DataMisfit(simulation=prbTD, data=dataTD)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh)
    opt = optimization.InexactGaussNewton(maxIterCG=10)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # directives
    beta = directives.BetaSchedule(coolingFactor=4, coolingRate=3)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1.0, seed=518936)
    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.0
    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
        # z_true = np.repeat(mesh.vectorCCz[active][1:], 2, axis=0)
        # z_true = np.r_[mesh.vectorCCz[active][0], z_true, mesh.vectorCCz[active][-1]]
        activeN = mesh.vectorNz <= 0.0 + cs / 2.0
        z_true = np.repeat(mesh.vectorNz[activeN][1:-1], 2, axis=0)
        z_true = np.r_[mesh.vectorNz[activeN][0], z_true, mesh.vectorNz[activeN][-1]]
        sigma_true = np.repeat(sigma[active], 2, axis=0)

        ax0.semilogx(sigma_true, z_true, "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, -dataFD.dobs[::2], "k-", lw=2, label="Obs (real)")
        ax1.plot(freqs, -dataFD.dobs[1::2], "k--", lw=2, label="Obs (imag)")

        dpredFD = prbFD.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.0, label="Pred (imag)"
        )

        ax2.loglog(times, dataTD.dobs, "k-", lw=2, label="Obs")
        ax2.loglog(
            times,
            prbTD.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)
                                    loc=np.r_[0.0, 0.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.Simulation3DMagneticFluxDensity(
    mesh=mesh, sigmaMap=maps.IdentityMap(mesh), timeSteps=ramp, Solver=Pardiso)
prob_ramp_on = TDEM.Simulation3DMagneticFluxDensity(
    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
# -------------------------------

t = time.time()
print("--- Running Long On-Time Simulation ---")
    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.0]  # 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),
        ]
        time_steps = 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(
            [],
            location=np.r_[0.0, 0.0, 0.0],
            orientation="z",
            radius=100,
        )

        src_ramp_on = tdem.Src.CircularLoop(
            [],
            location=np.r_[0.0, 0.0, 0.0],
            orientation="z",
            radius=100,
            waveform=waveform,
        )

        src_list = [src_magnetostatic]
        src_list_late_ontime = [src_ramp_on]

        survey = tdem.Survey(source_list=src_list)
        survey_late_ontime = tdem.Survey(src_list_late_ontime)

        prob = tdem.Simulation3DMagneticFluxDensity(
            mesh=mesh,
            survey=survey,
            time_steps=time_steps,
            sigmaMap=maps.IdentityMap(mesh),
            solver=Pardiso,
        )
        prob_late_ontime = tdem.Simulation3DMagneticFluxDensity(
            mesh=mesh,
            survey=survey_late_ontime,
            time_steps=time_steps,
            sigmaMap=maps.IdentityMap(mesh),
            solver=Pardiso,
        )

        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.0 / 1e-4 * np.ones(mesh.nC)) *
            w == prob.MfRho * w)

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

        prob.rho = 1.0 / 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.0 / 1e-3 * np.ones(mesh.nC)) *
            w == prob.MfRho * w)

        assert np.all(
            mesh.getFaceInnerProduct(1.0 / 1e-3 * np.ones(mesh.nC),
                                     invMat=True) * w == prob.MfRhoI * w)
def run(plotIt=True):

    cs, ncx, ncz, npad = 5.0, 25, 24, 15
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")

    active = mesh.vectorCCz < 0.0
    layer = (mesh.vectorCCz < -50.0) & (mesh.vectorCCz >= -150.0)
    actMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap
    sig_half = 1e-3
    sig_air = 1e-8
    sig_layer = 1e-2
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer
    mtrue = np.log(sigma[active])

    x = np.r_[30, 50, 70, 90]
    rxloc = np.c_[x, x * 0.0, np.zeros_like(x)]

    prb = TDEM.Simulation3DMagneticFluxDensity(mesh,
                                               sigmaMap=mapping,
                                               solver=Solver)
    prb.time_steps = [
        (1e-3, 5),
        (1e-4, 5),
        (5e-5, 10),
        (5e-5, 5),
        (1e-4, 10),
        (5e-4, 10),
    ]
    # Use VTEM waveform
    out = EMutils.VTEMFun(prb.times, 0.00595, 0.006, 100)

    # Forming function handle for waveform using 1D linear interpolation
    wavefun = interp1d(prb.times, out)
    t0 = 0.006
    waveform = TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun)

    rx = TDEM.Rx.PointMagneticFluxTimeDerivative(
        rxloc,
        np.logspace(-4, -2.5, 11) + t0, "z")
    src = TDEM.Src.CircularLoop([rx],
                                waveform=waveform,
                                loc=np.array([0.0, 0.0, 0.0]),
                                radius=10.0)
    survey = TDEM.Survey([src])
    prb.survey = survey

    # create observed data
    data = prb.make_synthetic_data(mtrue,
                                   relative_error=0.02,
                                   noise_floor=1e-11)

    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh)
    opt = optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)
    target = directives.TargetMisfit()
    # Create an inversion object
    beta = directives.BetaSchedule(coolingFactor=1.0, coolingRate=2.0)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    invProb.beta = 1e2
    inv = inversion.BaseInversion(invProb, directiveList=[beta, target])
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    prb.counter = opt.counter = utils.Counter()
    opt.remember("xc")
    mopt = inv.run(m0)

    if plotIt:
        fig, ax = plt.subplots(1, 2, figsize=(10, 6))
        Dobs = data.dobs.reshape((len(rx.times), len(x)))
        Dpred = invProb.dpred.reshape((len(rx.times), len(x)))
        for i in range(len(x)):
            ax[0].loglog(rx.times - t0, -Dobs[:, i].flatten(), "k")
            ax[0].loglog(rx.times - t0, -Dpred[:, i].flatten(), "k.")
            if i == 0:
                ax[0].legend(("$d^{obs}$", "$d^{pred}$"), fontsize=16)
        ax[0].set_xlabel("Time (s)", fontsize=14)
        ax[0].set_ylabel("$db_z / dt$ (nT/s)", fontsize=16)
        ax[0].set_xlabel("Time (s)", fontsize=14)
        ax[0].grid(color="k", alpha=0.5, linestyle="dashed", linewidth=0.5)

        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        plt.semilogx(np.exp(mopt), mesh.vectorCCz[active])
        ax[1].set_ylim(-600, 0)
        ax[1].set_xlim(1e-4, 1e-1)
        ax[1].set_xlabel("Conductivity (S/m)", fontsize=14)
        ax[1].set_ylabel("Depth (m)", fontsize=14)
        ax[1].grid(color="k", alpha=0.5, linestyle="dashed", linewidth=0.5)
        plt.legend(["$\sigma_{true}$", "$\sigma_{pred}$"])
def halfSpaceProblemAnaDiff(
    meshType,
    srctype="MagDipole",
    sig_half=1e-2,
    rxOffset=50.0,
    bounds=None,
    plotIt=False,
    rxType="MagneticFluxDensityz",
):

    if bounds is None:
        bounds = [1e-5, 1e-3]
    if meshType == "CYL":
        cs, ncx, ncz, npad = 15.0, 30, 10, 15
        hx = [(cs, ncx), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
        mesh = discretize.CylMesh([hx, 1, hz], "00C")

    elif meshType == "TENSOR":
        cs, nc, npad = 20.0, 13, 5
        hx = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        hy = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        mesh = discretize.TensorMesh([hx, hy, hz], "CCC")

    active = mesh.vectorCCz < 0.0
    actMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap

    prb = tdem.Simulation3DMagneticFluxDensity(mesh, sigmaMap=mapping)
    prb.Solver = Solver
    prb.timeSteps = [(1e-3, 5), (1e-4, 5), (5e-5, 10), (5e-5, 10), (1e-4, 10)]
    out = utils.VTEMFun(prb.times, 0.00595, 0.006, 100)
    wavefun = interp1d(prb.times, out)
    t0 = 0.006
    waveform = tdem.Src.RawWaveform(offTime=t0, waveFct=wavefun)

    rx = getattr(tdem.Rx,
                 "Point{}".format(rxType[:-1]))(np.array([[rxOffset, 0.0,
                                                           0.0]]),
                                                np.logspace(-4, -3, 31) + t0,
                                                rxType[-1])

    if srctype == "MagDipole":
        src = tdem.Src.MagDipole([rx],
                                 waveform=waveform,
                                 loc=np.array([0, 0.0, 0.0]))
    elif srctype == "CircularLoop":
        src = tdem.Src.CircularLoop([rx],
                                    waveform=waveform,
                                    loc=np.array([0.0, 0.0, 0.0]),
                                    radius=13.0)

    survey = tdem.Survey([src])
    prb.pair(survey)

    sigma = np.ones(mesh.nCz) * 1e-8
    sigma[active] = sig_half
    sigma = np.log(sigma[active])

    if srctype == "MagDipole":
        bz_ana = mu_0 * analytics.hzAnalyticDipoleT(rx.locations[0][0] + 1e-3,
                                                    rx.times - t0, sig_half)
    elif srctype == "CircularLoop":
        bz_ana = mu_0 * analytics.hzAnalyticCentLoopT(13, rx.times - t0,
                                                      sig_half)

    bz_calc = prb.dpred(sigma)
    ind = np.logical_and(rx.times - t0 > bounds[0], rx.times - t0 < bounds[1])
    log10diff = np.linalg.norm(
        np.log10(np.abs(bz_calc[ind])) -
        np.log10(np.abs(bz_ana[ind]))) / np.linalg.norm(
            np.log10(np.abs(bz_ana[ind])))

    print(" |bz_ana| = {ana} |bz_num| = {num} |bz_ana-bz_num| = {diff}".format(
        ana=np.linalg.norm(bz_ana),
        num=np.linalg.norm(bz_calc),
        diff=np.linalg.norm(bz_ana - bz_calc),
    ))
    print("Difference: {}".format(log10diff))

    if plotIt is True:
        plt.loglog(
            rx.times[bz_calc > 0] - t0,
            bz_calc[bz_calc > 0],
            "r",
            rx.times[bz_calc < 0] - t0,
            -bz_calc[bz_calc < 0],
            "r--",
        )
        plt.loglog(rx.times - t0, abs(bz_ana), "b*")
        plt.title("sig_half = {:e}".format(sig_half))
        plt.show()

    return log10diff
def halfSpaceProblemAnaDiff(
    meshType,
    srctype="MagDipole",
    sig_half=1e-2,
    rxOffset=50.0,
    bounds=None,
    plotIt=False,
    rxType="MagneticFluxDensityz",
):
    if bounds is None:
        bounds = [1e-5, 1e-3]
    if meshType == "CYL":
        cs, ncx, ncz, npad = 5.0, 30, 10, 15
        hx = [(cs, ncx), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
        mesh = discretize.CylMesh([hx, 1, hz], "00C")

    elif meshType == "TENSOR":
        cs, nc, npad = 20.0, 13, 5
        hx = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        hy = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)]
        mesh = discretize.TensorMesh([hx, hy, hz], "CCC")

    active = mesh.vectorCCz < 0.0
    actMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap

    rx = getattr(tdem.Rx,
                 "Point{}".format(rxType[:-1]))(np.array([[rxOffset, 0.0,
                                                           0.0]]),
                                                np.logspace(-5, -4, 21),
                                                rxType[-1])

    if srctype == "MagDipole":
        src = tdem.Src.MagDipole(
            [rx],
            waveform=tdem.Src.StepOffWaveform(),
            location=np.array([0.0, 0.0, 0.0]),
        )
    elif srctype == "CircularLoop":
        src = tdem.Src.CircularLoop(
            [rx],
            waveform=tdem.Src.StepOffWaveform(),
            location=np.array([0.0, 0.0, 0.0]),
            radius=0.1,
        )

    survey = tdem.Survey([src])

    time_steps = [
        (1e-06, 40),
        (5e-06, 40),
        (1e-05, 40),
        (5e-05, 40),
        (0.0001, 40),
        (0.0005, 40),
    ]

    prb = tdem.Simulation3DMagneticFluxDensity(mesh,
                                               survey=survey,
                                               time_steps=time_steps,
                                               sigmaMap=mapping)
    prb.solver = Solver

    sigma = np.ones(mesh.nCz) * 1e-8
    sigma[active] = sig_half
    sigma = np.log(sigma[active])
    if srctype == "MagDipole":
        bz_ana = mu_0 * analytics.hzAnalyticDipoleT(rx.locations[0][0] + 1e-3,
                                                    rx.times, sig_half)
    elif srctype == "CircularLoop":
        bz_ana = mu_0 * analytics.hzAnalyticDipoleT(13, rx.times, sig_half)

    bz_calc = prb.dpred(sigma)
    ind = np.logical_and(rx.times > bounds[0], rx.times < bounds[1])
    log10diff = np.linalg.norm(
        np.log10(np.abs(bz_calc[ind])) -
        np.log10(np.abs(bz_ana[ind]))) / np.linalg.norm(
            np.log10(np.abs(bz_ana[ind])))

    print(" |bz_ana| = {ana} |bz_num| = {num} |bz_ana-bz_num| = {diff}".format(
        ana=np.linalg.norm(bz_ana),
        num=np.linalg.norm(bz_calc),
        diff=np.linalg.norm(bz_ana - bz_calc),
    ))
    print("Difference: {}".format(log10diff))

    if plotIt is True:
        plt.loglog(
            rx.times[bz_calc > 0],
            bz_calc[bz_calc > 0],
            "r",
            rx.times[bz_calc < 0],
            -bz_calc[bz_calc < 0],
            "r--",
        )
        plt.loglog(rx.times, abs(bz_ana), "b*")
        plt.title("sig_half = {0:e}".format(sig_half))
        plt.show()

    return log10diff
示例#8
0
def run_simulation(fname="tdem_gs_half.h5",
                   sigma_block=0.01,
                   sigma_halfspace=0.01):
    from SimPEG.electromagnetics import time_domain as tdem
    from SimPEG.electromagnetics.utils import waveform_utils
    from scipy.constants import mu_0
    import numpy as np
    from SimPEG import maps, utils
    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 = 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

    t0 = 0.01 + 1e-4
    times = np.logspace(-4, -2, 21)
    rx_ex = tdem.receivers.PointElectricField(xyz, times + t0, orientation="x")
    rx_ey = tdem.receivers.PointElectricField(xyz, times + t0, orientation="y")
    rx_by = tdem.receivers.PointElectricField(xyz, times + t0, orientation="y")

    rxList = [rx_ex, rx_ey, rx_by]

    sim = tdem.Simulation3DMagneticFluxDensity(mesh, sigma=sigma, verbose=True)
    sim.Solver = Pardiso
    sim.solverOpts = {"is_symmetric": False}
    sim.time_steps = [(1e-3, 10), (2e-5, 10), (1e-4, 10), (5e-4, 10),
                      (1e-3, 10)]
    t0 = 0.01 + 1e-4
    out = waveform_utils.VTEMFun(sim.times, 0.01, t0, 200)
    wavefun = interp1d(sim.times, out)
    waveform = tdem.sources.RawWaveform(offTime=t0, waveFct=wavefun)

    src = tdem.sources.LineCurrent(rxList, loc=srcLoc, waveform=waveform)
    survey = tdem.survey.Survey([src])
    sim.survey = survey
    input_currents = wavefun(sim.times)

    f = sim.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": sim.times - t0,
        "input_currents": input_currents,
    }
    dd.io.save(fname, tdem_gs)
src_list_ramp_on = [src_ramp_on]

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

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

prob_magnetostatic = TDEM.Simulation3DMagneticFluxDensity(
    mesh=mesh,
    survey=survey_magnetostatic,
    sigmaMap=maps.IdentityMap(mesh),
    time_steps=ramp,
    solver=Solver,
)
prob_ramp_on = TDEM.Simulation3DMagneticFluxDensity(
    mesh=mesh,
    survey=survey_ramp_on,
    sigmaMap=maps.IdentityMap(mesh),
    time_steps=ramp,
    solver=Solver,
)

###############################################################################
# Run the long on-time simulation
# -------------------------------
示例#10
0
def run_simulation(fname="tdem_vmd.h5", sigma_halfspace=0.01, src_type="VMD"):
    from SimPEG.electromagnetics import time_domain
    from scipy.constants import mu_0
    import numpy as np
    from SimPEG import maps
    from pymatsolver import Pardiso

    cs = 20.0
    ncx, ncy, ncz = 5, 3, 4
    npad = 10
    npadz = 10
    pad_rate = 1.3
    hx = [(cs, npad, -pad_rate), (cs, ncx), (cs, npad, pad_rate)]
    hy = [(cs, npad, -pad_rate), (cs, ncy), (cs, npad, pad_rate)]
    hz = utils.meshTensor([(cs, npadz, -1.3), (cs / 2.0, ncz), (cs, 5, 2)])
    mesh = TensorMesh([hx, hy, hz],
                      x0=["C", "C", -hz[:int(npadz + ncz / 2)].sum()])
    sigma = np.ones(mesh.nC) * sigma_halfspace
    sigma[mesh.gridCC[:, 2] > 0.0] = 1e-8

    xmin, xmax = -600.0, 600.0
    ymin, ymax = -600.0, 600.0
    zmin, zmax = -600, 100.0

    times = np.logspace(-5, -2, 21)
    rxList = time_domain.receivers.PointMagneticFluxTimeDerivative(
        np.r_[10.0, 0.0, 30.0], times, orientation="z")
    if src_type == "VMD":
        src = time_domain.sources.CircularLoop(
            [rxList],
            loc=np.r_[0.0, 0.0, 30.0],
            orientation="Z",
            waveform=time_domain.sources.StepOffWaveform(),
            radius=13.0,
        )
    elif src_type == "HMD":
        src = time_domain.sources.MagDipole(
            [rxList],
            loc=np.r_[0.0, 0.0, 30.0],
            orientation="X",
            waveform=time_domain.sources.StepOffWaveform(),
        )
    SrcList = [src]
    survey = time_domain.Survey(SrcList)
    sig = 1e-2
    sigma = np.ones(mesh.nC) * sig
    sigma[mesh.gridCC[:, 2] > 0] = 1e-8
    prb = time_domain.Simulation3DMagneticFluxDensity(
        mesh,
        sigmaMap=maps.IdentityMap(mesh),
        verbose=True,
        survey=survey,
        solver=Pardiso,
    )
    prb.time_steps = [
        (1e-06, 5),
        (5e-06, 5),
        (1e-05, 10),
        (5e-05, 10),
        (1e-4, 15),
        (5e-4, 16),
    ]

    f = prb.fields(sigma)

    xyzlim = np.array([[xmin, xmax], [ymin, ymax], [zmin, zmax]])
    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_is = {
        "E": E,
        "B": B,
        "J": J,
        "sigma": sigma_core,
        "mesh": meshCore.serialize(),
        "time": prb.times,
    }
    dd.io.save(fname, tdem_is)