Exemple #1
0
def setUp_TDEM(prbtype="ElectricField", rxcomp="ElectricFieldx"):
    cs = 5.0
    ncx = 8
    ncy = 8
    ncz = 8
    npad = 0
    # hx = [(cs, ncx), (cs, npad, 1.3)]
    # hz = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)]
    mesh = discretize.TensorMesh(
        [
            [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)],
            [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)],
            [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)],
        ],
        "CCC",
    )
    #
    active = mesh.vectorCCz < 0.0
    activeMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * activeMap

    rxOffset = 0.0
    rxlocs = np.array([[20, 20.0, 0.0]])
    rxtimes = np.logspace(-4, -3, 20)
    rx = getattr(tdem.Rx,
                 "Point{}".format(rxcomp[:-1]))(locations=rxlocs,
                                                times=rxtimes,
                                                orientation=rxcomp[-1])
    Aloc = np.r_[-10.0, 0.0, 0.0]
    Bloc = np.r_[10.0, 0.0, 0.0]
    srcloc = np.vstack((Aloc, Bloc))

    src = tdem.Src.LineCurrent([rx],
                               location=srcloc,
                               waveform=tdem.Src.StepOffWaveform())
    survey = tdem.Survey([src])

    prb = getattr(tdem, "Simulation3D{}".format(prbtype))(mesh,
                                                          sigmaMap=mapping)

    prb.time_steps = [(1e-05, 10), (5e-05, 10), (2.5e-4, 10)]

    prb.solver = Solver

    m = np.log(1e-1) * np.ones(prb.sigmaMap.nP) + 1e-3 * np.random.randn(
        prb.sigmaMap.nP)

    prb.pair(survey)
    mesh = mesh

    return prb, m, mesh
Exemple #2
0
    def setUp(self):
        mesh = discretize.TensorMesh([30])
        sigma = np.ones(mesh.nC)
        model = np.log(sigma)

        receivers = survey.BaseRx(20 * [[0.0]])
        source = survey.BaseSrc([receivers])

        self.sim = simulation.ExponentialSinusoidSimulation(
            mesh=mesh,
            survey=survey.BaseSurvey([source]),
            model_map=maps.ExpMap(mesh))

        self.dobs = self.sim.dpred(model)
    def test_property_mirroring(self):
        mesh = discretize.TensorMesh([8, 7, 6])

        for regType in ["Tikhonov", "Sparse", "Simple"]:
            reg = getattr(regularization, regType)(mesh)

            print(reg.nP, mesh.nC)
            self.assertTrue(reg.nP == mesh.nC)

            # Test assignment of active indices
            indActive = mesh.gridCC[:, 2] < 0.6
            reg.indActive = indActive

            self.assertTrue(reg.nP == int(indActive.sum()))

            [
                self.assertTrue(np.all(fct.indActive == indActive))
                for fct in reg.objfcts
            ]

            # test assignment of cell weights
            cell_weights = np.random.rand(indActive.sum())
            reg.cell_weights = cell_weights
            [
                self.assertTrue(np.all(fct.cell_weights == cell_weights))
                for fct in reg.objfcts
            ]

            # test updated mappings
            mapping = maps.ExpMap(nP=int(indActive.sum()))
            reg.mapping = mapping
            m = np.random.rand(mapping.nP)
            [
                self.assertTrue(np.all(fct.mapping * m == mapping * m))
                for fct in reg.objfcts
            ]

            # test alphas
            m = np.random.rand(reg.nP)
            a = reg(m)
            [
                setattr(
                    reg,
                    "{}".format(objfct._multiplier_pair),
                    0.5 * getattr(reg, "{}".format(objfct._multiplier_pair)),
                ) for objfct in reg.objfcts
            ]
            b = reg(m)
            self.assertTrue(0.5 * a == b)
Exemple #4
0
    def test_sum(self):
        M2 = discretize.TensorMesh([np.ones(10), np.ones(20)], "CC")
        block = maps.ParametricEllipsoid(M2) * maps.Projection(
            7, np.r_[1, 2, 3, 4, 5, 6])
        background = (maps.ExpMap(M2) * maps.SurjectFull(M2) *
                      maps.Projection(7, np.r_[0]))

        summap0 = maps.SumMap([block, background])
        summap1 = block + background

        m0 = np.hstack([
            np.random.rand(3),
            np.r_[M2.x0[0], 2 * M2.hx.min()],
            np.r_[M2.x0[1], 4 * M2.hy.min()],
        ])

        self.assertTrue(np.all(summap0 * m0 == summap1 * m0))

        self.assertTrue(summap0.test(m0))
        self.assertTrue(summap1.test(m0))
Exemple #5
0
    def test_vangenuchten_k_m(self):
        mesh = discretize.TensorMesh([50])

        expmap = maps.ExpMap(nP=mesh.nC)
        idnmap = maps.IdentityMap(nP=mesh.nC)

        seeds = {
            "Ks":
            np.random.triangular(np.log(1e-7), np.log(1e-6), np.log(1e-5),
                                 mesh.nC),
            "I":
            np.random.rand(mesh.nC),
            "n":
            np.random.rand(mesh.nC) + 1,
            "alpha":
            np.random.rand(mesh.nC),
        }

        opts = [
            ("Ks", dict(KsMap=expmap), 1),
            ("I", dict(IMap=idnmap), 1),
            ("n", dict(nMap=idnmap), 1),
            ("alpha", dict(alphaMap=idnmap), 1),
        ]

        u = np.random.randn(mesh.nC)

        for name, opt, nM in opts:
            van = richards.empirical.Vangenuchten_k(mesh, **opt)

            x0 = np.concatenate([seeds[n] for n in name.split("-")])

            def fun(m):
                van.model = m
                return van(u), van.derivM(u)

            print("Vangenuchten_k test m deriv:  ", name)

            passed = checkDerivative(fun, x0, plotIt=False)
            self.assertTrue(passed, True)
Exemple #6
0
    def setUp(self):
        cs = 10
        nc = 20
        npad = 10
        mesh = discretize.CylMesh([
            [(cs, nc), (cs, npad, 1.3)],
            np.r_[2 * np.pi],
            [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)],
        ])

        mesh.x0 = np.r_[0.0, 0.0, -mesh.hz[:npad + nc].sum()]

        # receivers
        rx_x = np.linspace(10, 200, 20)
        rx_z = np.r_[-5]
        rx_locs = utils.ndgrid([rx_x, np.r_[0], rx_z])
        rx_list = [
            dc.receivers.BaseRx(rx_locs, projField="e", orientation="x")
        ]

        # sources
        src_a = np.r_[0.0, 0.0, -5.0]
        src_b = np.r_[55.0, 0.0, -5.0]

        src_list = [
            dc.sources.Dipole(rx_list, locationA=src_a, locationB=src_b)
        ]

        self.mesh = mesh
        self.survey = dc.survey.Survey(src_list)
        self.sigma_map = maps.ExpMap(mesh) * maps.InjectActiveCells(
            mesh, mesh.gridCC[:, 2] <= 0, np.log(1e-8))
        self.prob = dc.simulation.Simulation3DCellCentered(
            mesh=mesh,
            survey=self.survey,
            sigmaMap=self.sigma_map,
            Solver=Pardiso,
            bc_type="Dirichlet",
        )
def getSensitivity(survey, A, B, M, N, model):
    src_type, rx_type = survey.split("-")
    if rx_type == "Pole":
        rx = DC.receivers.Pole(np.r_[M, 0.0])
    else:
        rx = DC.receivers.Dipole(np.r_[M, 0.0], np.r_[N, 0.0])
    if src_type == "Pole":
        src = DC.sources.Pole([rx], np.r_[A, 0.0])
    else:
        src = DC.sources.Dipole([rx], np.r_[A, 0.0], np.r_[B, 0.0])

    # Model mappings
    expmap = maps.ExpMap(mesh)
    mapping = expmap

    survey = DC.Survey([src])
    sim = DC.Simulation3DCellCentered(
        mesh, sigmaMap=mapping, solver=Pardiso, survey=survey
    )
    J = sim.getJ(model)[0]

    return J
Exemple #8
0
    def test_reciprocal_no_map(self):
        expMap = maps.ExpMap(discretize.TensorMesh((3,)))

        PM = ReciprocalExample()
        self.assertRaises(AttributeError, getattr, PM, "sigma")

        PM.sigmaMap = expMap
        # PM = pickle.loads(pickle.dumps(PM))
        PM.model = np.r_[1.0, 2.0, 3.0]
        assert np.all(PM.sigma == np.exp(np.r_[1.0, 2.0, 3.0]))
        assert np.all(PM.rho == 1.0 / np.exp(np.r_[1.0, 2.0, 3.0]))

        PM.rho = np.r_[1.0, 2.0, 3.0]
        assert PM.sigmaMap is None
        assert PM.sigmaDeriv == 0
        assert np.all(PM.sigma == 1.0 / np.r_[1.0, 2.0, 3.0])

        PM.sigmaMap = expMap
        assert len(PM.sigmaMap) == 1
        # PM = pickle.loads(pickle.dumps(PM))
        assert np.all(PM.rho == 1.0 / np.exp(np.r_[1.0, 2.0, 3.0]))
        assert np.all(PM.sigma == np.exp(np.r_[1.0, 2.0, 3.0]))
        assert isinstance(PM.sigmaDeriv.todense(), np.ndarray)
Exemple #9
0
    def setUp(self):
        cs = 10.0
        ncx, ncy, ncz = 30.0, 30.0, 30.0
        npad = 10.0
        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)]
        self.mesh = discretize.TensorMesh([hx, hy, hz], "CCC")
        mapping = maps.ExpMap(self.mesh)

        self.frequency = 1.0

        self.prob_e = fdem.Simulation3DElectricField(self.mesh,
                                                     sigmaMap=mapping)
        self.prob_b = fdem.Simulation3DMagneticFluxDensity(self.mesh,
                                                           sigmaMap=mapping)
        self.prob_h = fdem.Simulation3DMagneticField(self.mesh,
                                                     sigmaMap=mapping)
        self.prob_j = fdem.Simulation3DCurrentDensity(self.mesh,
                                                      sigmaMap=mapping)

        loc = np.r_[0.0, 0.0, 0.0]
        self.location = utils.mkvc(
            self.mesh.gridCC[utils.closestPoints(self.mesh, loc, "CC"), :])
from discretize import TensorMesh
from SimPEG import maps, SolverLU, utils
from SimPEG.utils import ExtractCoreMesh
from SimPEG.electromagnetics.static import resistivity as DC

from ..base import widgetify

# Mesh, mapping can be globals global
npad = 15
growrate = 2.0
cs = 0.5
hx = [(cs, npad, -growrate), (cs, 200), (cs, npad, growrate)]
hy = [(cs, npad, -growrate), (cs, 100)]
mesh = TensorMesh([hx, hy], "CN")
expmap = maps.ExpMap(mesh)
mapping = expmap
dx = 5
xr = np.arange(-40, 41, dx)
dxr = np.diff(xr)
xmin = -40.0
xmax = 40.0
ymin = -40.0
ymax = 8.0
xylim = np.c_[[xmin, ymin], [xmax, ymax]]
indCC, meshcore = ExtractCoreMesh(xylim, mesh)
indx = (
    (mesh.gridFx[:, 0] >= xmin)
    & (mesh.gridFx[:, 0] <= xmax)
    & (mesh.gridFx[:, 1] >= ymin)
    & (mesh.gridFx[:, 1] <= ymax)
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
def run(plotIt=True, saveFig=False, cleanup=True):
    """
    Run 1D inversions for a single sounding of the RESOLVE and SkyTEM
    bookpurnong data

    :param bool plotIt: show the plots?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """
    downloads, directory = download_and_unzip_data()

    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")
    skytem = h5py.File(os.path.sep.join([directory, "booky_skytem.hdf5"]), "r")
    river_path = resolve["river_path"].value

    # Choose a sounding location to invert
    xloc, yloc = 462100.0, 6196500.0
    rxind_skytem = np.argmin(
        abs(skytem["xy"][:, 0] - xloc) + abs(skytem["xy"][:, 1] - yloc))
    rxind_resolve = np.argmin(
        abs(resolve["xy"][:, 0] - xloc) + abs(resolve["xy"][:, 1] - yloc))

    # Plot both resolve and skytem data on 2D plane
    fig = plt.figure(figsize=(13, 6))
    title = ["RESOLVE In-phase 400 Hz", "SkyTEM High moment 156 $\mu$s"]
    ax1 = plt.subplot(121)
    ax2 = plt.subplot(122)
    axs = [ax1, ax2]
    out_re = utils.plot2Ddata(
        resolve["xy"],
        resolve["data"][:, 0],
        ncontour=100,
        contourOpts={"cmap": "viridis"},
        ax=ax1,
    )
    vmin, vmax = out_re[0].get_clim()
    cb_re = plt.colorbar(out_re[0],
                         ticks=np.linspace(vmin, vmax, 3),
                         ax=ax1,
                         fraction=0.046,
                         pad=0.04)
    temp_skytem = skytem["data"][:, 5].copy()
    temp_skytem[skytem["data"][:, 5] > 7e-10] = 7e-10
    out_sky = utils.plot2Ddata(
        skytem["xy"][:, :2],
        temp_skytem,
        ncontour=100,
        contourOpts={
            "cmap": "viridis",
            "vmax": 7e-10
        },
        ax=ax2,
    )
    vmin, vmax = out_sky[0].get_clim()
    cb_sky = plt.colorbar(
        out_sky[0],
        ticks=np.linspace(vmin, vmax * 0.99, 3),
        ax=ax2,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb_re.set_label("Bz (ppm)")
    cb_sky.set_label("dB$_z$ / dt (V/A-m$^4$)")

    for i, ax in enumerate(axs):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        ax.plot(xloc, yloc, "wo")
        ax.plot(river_path[:, 0], river_path[:, 1], "k", lw=0.5)

        ax.set_aspect("equal")
        if i == 1:
            ax.plot(skytem["xy"][:, 0],
                    skytem["xy"][:, 1],
                    "k.",
                    alpha=0.02,
                    ms=1)
            ax.set_yticklabels([str(" ") for f in yticks])
        else:
            ax.plot(resolve["xy"][:, 0],
                    resolve["xy"][:, 1],
                    "k.",
                    alpha=0.02,
                    ms=1)
            ax.set_yticklabels([str(f) for f in yticks])
            ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])
        ax.axis("equal")
    # plt.tight_layout()

    if saveFig is True:
        fig.savefig("resolve_skytem_data.png", dpi=600)

    # ------------------ Mesh ------------------ #
    # Step1: Set 2D cylindrical mesh
    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.0

    # Step2: Set a SurjectVertical1D mapping
    # Note: this sets our inversion model as 1D log conductivity
    # below subsurface

    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
    sig_half = 1e-1
    sig_air = 1e-8
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half

    # Initial and reference model
    m0 = np.log(sigma[active])

    # ------------------ RESOLVE Forward Simulation ------------------ #
    # Step3: Invert Resolve data

    # Bird height from the surface
    b_height_resolve = resolve["src_elevation"].value
    src_height_resolve = b_height_resolve[rxind_resolve]

    # Set Rx (In-phase and Quadrature)
    rxOffset = 7.86
    bzr = FDEM.Rx.PointMagneticFluxDensitySecondary(
        np.array([[rxOffset, 0.0, src_height_resolve]]),
        orientation="z",
        component="real",
    )

    bzi = FDEM.Rx.PointMagneticFluxDensity(
        np.array([[rxOffset, 0.0, src_height_resolve]]),
        orientation="z",
        component="imag",
    )

    # Set Source (In-phase and Quadrature)
    frequency_cp = resolve["frequency_cp"].value
    freqs = frequency_cp.copy()
    srcLoc = np.array([0.0, 0.0, src_height_resolve])
    srcList = [
        FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation="Z")
        for freq in freqs
    ]

    # Set FDEM survey (In-phase and Quadrature)
    survey = FDEM.Survey(srcList)
    prb = FDEM.Simulation3DMagneticFluxDensity(mesh,
                                               sigmaMap=mapping,
                                               Solver=Solver)
    prb.survey = survey

    # ------------------ RESOLVE Inversion ------------------ #

    # Primary field
    bp = -mu_0 / (4 * np.pi * rxOffset**3)

    # Observed data
    cpi_inds = [0, 2, 6, 8, 10]
    cpq_inds = [1, 3, 7, 9, 11]
    dobs_re = (np.c_[resolve["data"][rxind_resolve, :][cpi_inds],
                     resolve["data"][rxind_resolve, :][cpq_inds], ].flatten() *
               bp * 1e-6)

    # Uncertainty
    relative = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
    floor = 20 * abs(bp) * 1e-6
    std = abs(dobs_re) * relative + floor

    # Data Misfit
    data_resolve = data.Data(dobs=dobs_re,
                             survey=survey,
                             standard_deviation=std)
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data_resolve)

    # Regularization
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh, mapping=maps.IdentityMap(regMesh))

    # Optimization
    opt = optimization.InexactGaussNewton(maxIter=5)

    # statement of the inverse problem
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion directives and parameters
    target = directives.TargetMisfit()  # stop when we hit target misfit
    invProb.beta = 2.0
    inv = inversion.BaseInversion(invProb, directiveList=[target])
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.0
    reg.mref = m0.copy()
    opt.LSshorten = 0.5
    opt.remember("xc")
    # run the inversion
    mopt_re = inv.run(m0)
    dpred_re = invProb.dpred

    # ------------------ SkyTEM Forward Simulation ------------------ #
    # Step4: Invert SkyTEM data

    # Bird height from the surface
    b_height_skytem = skytem["src_elevation"].value
    src_height = b_height_skytem[rxind_skytem]
    srcLoc = np.array([0.0, 0.0, src_height])

    # Radius of the source loop
    area = skytem["area"].value
    radius = np.sqrt(area / np.pi)
    rxLoc = np.array([[radius, 0.0, src_height]])

    # Parameters for current waveform
    t0 = skytem["t0"].value
    times = skytem["times"].value
    waveform_skytem = skytem["waveform"].value
    offTime = t0
    times_off = times - t0

    # Note: we are Using theoretical VTEM waveform,
    # but effectively fits SkyTEM waveform
    peakTime = 1.0000000e-02
    a = 3.0

    dbdt_z = TDEM.Rx.PointMagneticFluxTimeDerivative(
        locations=rxLoc, times=times_off[:-3] + offTime,
        orientation="z")  # vertical db_dt

    rxList = [dbdt_z]  # list of receivers
    srcList = [
        TDEM.Src.CircularLoop(
            rxList,
            loc=srcLoc,
            radius=radius,
            orientation="z",
            waveform=TDEM.Src.VTEMWaveform(offTime=offTime,
                                           peakTime=peakTime,
                                           a=3.0),
        )
    ]
    # solve the problem at these times
    timeSteps = [
        (peakTime / 5, 5),
        ((offTime - peakTime) / 5, 5),
        (1e-5, 5),
        (5e-5, 5),
        (1e-4, 10),
        (5e-4, 15),
    ]
    prob = TDEM.Simulation3DElectricField(mesh,
                                          time_steps=timeSteps,
                                          sigmaMap=mapping,
                                          Solver=Solver)
    survey = TDEM.Survey(srcList)
    prob.survey = survey

    src = srcList[0]
    rx = src.receiver_list[0]
    wave = []
    for time in prob.times:
        wave.append(src.waveform.eval(time))
    wave = np.hstack(wave)
    out = prob.dpred(m0)

    # plot the waveform
    fig = plt.figure(figsize=(5, 3))
    times_off = times - t0
    plt.plot(waveform_skytem[:, 0], waveform_skytem[:, 1], "k.")
    plt.plot(prob.times, wave, "k-", lw=2)
    plt.legend(("SkyTEM waveform", "Waveform (fit)"), fontsize=10)
    for t in rx.times:
        plt.plot(np.ones(2) * t, np.r_[-0.03, 0.03], "k-")
    plt.ylim(-0.1, 1.1)
    plt.grid(True)
    plt.xlabel("Time (s)")
    plt.ylabel("Normalized current")

    if saveFig:
        fig.savefig("skytem_waveform", dpi=200)

    # Observed data
    dobs_sky = skytem["data"][rxind_skytem, :-3] * area

    # ------------------ SkyTEM Inversion ------------------ #
    # Uncertainty
    relative = 0.12
    floor = 7.5e-12
    std = abs(dobs_sky) * relative + floor

    # Data Misfit
    data_sky = data.Data(dobs=-dobs_sky, survey=survey, standard_deviation=std)
    dmisfit = data_misfit.L2DataMisfit(simulation=prob, data=data_sky)

    # Regularization
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Simple(regMesh, mapping=maps.IdentityMap(regMesh))

    # Optimization
    opt = optimization.InexactGaussNewton(maxIter=5)

    # statement of the inverse problem
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Directives and Inversion Parameters
    target = directives.TargetMisfit()
    invProb.beta = 20.0
    inv = inversion.BaseInversion(invProb, directiveList=[target])
    reg.alpha_s = 1e-1
    reg.alpha_x = 1.0
    opt.LSshorten = 0.5
    opt.remember("xc")
    reg.mref = mopt_re  # Use RESOLVE model as a reference model

    # run the inversion
    mopt_sky = inv.run(m0)
    dpred_sky = invProb.dpred

    # Plot the figure from the paper
    plt.figure(figsize=(12, 8))

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

    ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2)
    ax1 = plt.subplot2grid((2, 2), (0, 1))
    ax2 = plt.subplot2grid((2, 2), (1, 1))

    # Recovered Models
    sigma_re = np.repeat(np.exp(mopt_re), 2, axis=0)
    sigma_sky = np.repeat(np.exp(mopt_sky), 2, axis=0)
    z = np.repeat(mesh.vectorCCz[active][1:], 2, axis=0)
    z = np.r_[mesh.vectorCCz[active][0], z, mesh.vectorCCz[active][-1]]

    ax0.semilogx(sigma_re, z, "k", lw=2, label="RESOLVE")
    ax0.semilogx(sigma_sky, z, "b", lw=2, label="SkyTEM")
    ax0.set_ylim(-50, 0)
    # ax0.set_xlim(5e-4, 1e2)
    ax0.grid(True)
    ax0.set_ylabel("Depth (m)")
    ax0.set_xlabel("Conducivity (S/m)")
    ax0.legend(loc=3)
    ax0.set_title("(a) Recovered Models")

    # RESOLVE Data
    ax1.loglog(frequency_cp,
               dobs_re.reshape((5, 2))[:, 0] / bp * 1e6,
               "k-",
               label="Obs (real)")
    ax1.loglog(
        frequency_cp,
        dobs_re.reshape((5, 2))[:, 1] / bp * 1e6,
        "k--",
        label="Obs (imag)",
    )
    ax1.loglog(
        frequency_cp,
        dpred_re.reshape((5, 2))[:, 0] / bp * 1e6,
        "k+",
        ms=10,
        markeredgewidth=2.0,
        label="Pred (real)",
    )
    ax1.loglog(
        frequency_cp,
        dpred_re.reshape((5, 2))[:, 1] / bp * 1e6,
        "ko",
        ms=6,
        markeredgecolor="k",
        markeredgewidth=0.5,
        label="Pred (imag)",
    )
    ax1.set_title("(b) RESOLVE")
    ax1.set_xlabel("Frequency (Hz)")
    ax1.set_ylabel("Bz (ppm)")
    ax1.grid(True)
    ax1.legend(loc=3, fontsize=11)

    # SkyTEM data
    ax2.loglog(times_off[3:] * 1e6, dobs_sky / area, "b-", label="Obs")
    ax2.loglog(
        times_off[3:] * 1e6,
        -dpred_sky / area,
        "bo",
        ms=4,
        markeredgecolor="k",
        markeredgewidth=0.5,
        label="Pred",
    )
    ax2.set_xlim(times_off.min() * 1e6 * 1.2, times_off.max() * 1e6 * 1.1)

    ax2.set_xlabel("Time ($\mu s$)")
    ax2.set_ylabel("dBz / dt (V/A-m$^4$)")
    ax2.set_title("(c) SkyTEM High-moment")
    ax2.grid(True)
    ax2.legend(loc=3)

    a3 = plt.axes([0.86, 0.33, 0.1, 0.09], facecolor=[0.8, 0.8, 0.8, 0.6])
    a3.plot(prob.times * 1e6, wave, "k-")
    a3.plot(rx.times * 1e6,
            np.zeros_like(rx.times),
            "k|",
            markeredgewidth=1,
            markersize=12)
    a3.set_xlim([prob.times.min() * 1e6 * 0.75, prob.times.max() * 1e6 * 1.1])
    a3.set_title("(d) Waveform", fontsize=11)
    a3.set_xticks([prob.times.min() * 1e6, t0 * 1e6, prob.times.max() * 1e6])
    a3.set_yticks([])
    # a3.set_xticklabels(['0', '2e4'])
    a3.set_xticklabels(["-1e4", "0", "1e4"])

    plt.tight_layout()

    if saveFig:
        plt.savefig("booky1D_time_freq.png", dpi=600)

    if plotIt:
        plt.show()

    resolve.close()
    skytem.close()
    if cleanup:
        print(os.path.split(directory)[:-1])
        os.remove(
            os.path.sep.join(directory.split()[:-1] +
                             ["._bookpurnong_inversion"]))
        os.remove(downloads)
        shutil.rmtree(directory)
# well as the mapping from the model space to the active cells. Starting and
# reference models can be a constant background value or contain a-priori
# structures. Here, the starting model is the natural log of 0.01 S/m.
#

# Define conductivity model in S/m
air_conductivity = np.log(1e-8)
background_conductivity = np.log(1e-2)

# Find the indecies of the active cells in forward model (ones below surface)
ind_active = surface2ind_topo(mesh, xyz_topo)

active_map = maps.InjectActiveCells(mesh, ind_active, np.exp(air_conductivity))
nC = int(ind_active.sum())

model_map = active_map * maps.ExpMap()

# Define model
starting_model = background_conductivity * np.ones(nC)

##############################################
# Define the Physics
# ------------------
#
# Here, we define the physics of the gravity problem by using the simulation
# class.
#

simulation = fdem.simulation.Simulation3DMagneticFluxDensity(
    mesh, survey=survey, sigmaMap=model_map, Solver=Solver)
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}$"])
Exemple #15
0
# Define the model on subsurface cells
model = background_value * np.ones(ind_active.sum())
ind_dyke = (mesh.gridCC[ind_active, 0] > 20.0) & (mesh.gridCC[ind_active, 0] <
                                                  40.0)
model[ind_dyke] = dyke_value
ind_block = ((mesh.gridCC[ind_active, 0] > -40.0)
             & (mesh.gridCC[ind_active, 0] < -10.0)
             & (mesh.gridCC[ind_active, 1] > -30.0)
             & (mesh.gridCC[ind_active, 1] < 30.0)
             & (mesh.gridCC[ind_active, 2] > -40.0)
             & (mesh.gridCC[ind_active, 2] < 0.0))
model[ind_block] = block_value

# Define a single mapping from model to mesh
exponential_map = maps.ExpMap()
reciprocal_map = maps.ReciprocalMap()
model_map = active_map * reciprocal_map * exponential_map

# Plot
fig = plt.figure(figsize=(5, 5))
ax = fig.add_subplot(111)
ind_slice = int(mesh.hy.size / 2)
mesh.plotSlice(model_map * model, normal="Y", ax=ax, ind=ind_slice, grid=True)
ax.set_title("Model slice at y = {} m".format(mesh.x0[1] +
                                              np.sum(mesh.hy[0:ind_slice])))
plt.show()

#############################################
# Models with arbitrary shapes
# ----------------------------
#
# Here, we create starting and/or reference models for the inversion as
# well as the mapping from the model space to the active cells. Starting and
# reference models can be a constant background value or contain a-priori
# structures. Here, the starting model is log(1000) Ohm meters.
#
# Define log-resistivity values for each layer since our model is the
# log-resistivity. Don't make the values 0!
# Otherwise the gradient for the 1st iteration is zero and the inversion will
# not converge.

# Define model. A resistivity (Ohm meters) or conductivity (S/m) for each layer.
starting_model = np.log(2e2 * np.ones((len(layer_thicknesses) + 1)))

# Define mapping from model to active cells.
model_map = maps.IdentityMap(nP=len(starting_model)) * maps.ExpMap()

#######################################################################
# Define the Physics
# ------------------
#
# Here we define the physics of the problem using the Simulation1DLayers class.
#

simulation = dc.simulation_1d.Simulation1DLayers(
    survey=survey,
    rhoMap=model_map,
    thicknesses=layer_thicknesses,
    data_type="apparent_resistivity",
)
layer_thicknesses = np.r_[50.0, 50.0]

# Define a mesh for plotting and regularization.
mesh = TensorMesh([(np.r_[layer_thicknesses, layer_thicknesses[-1]])], "0")
print(mesh)

# Define model. We are inverting for the layer resistivities and layer thicknesses.
# Since the bottom layer extends to infinity, it is not a model parameter for
# which we need to invert. For a 3 layer model, there is a total of 5 parameters.
# For stability, our model is the log-resistivity and log-thickness.
starting_model = np.r_[np.log(resistivities), np.log(layer_thicknesses)]

# Since the model contains two different properties for each layer, we use
# wire maps to distinguish the properties.
wire_map = maps.Wires(("rho", mesh.nC), ("t", mesh.nC - 1))
resistivity_map = maps.ExpMap(nP=mesh.nC) * wire_map.rho
layer_map = maps.ExpMap(nP=mesh.nC - 1) * wire_map.t

#######################################################################
# Define the Physics
# ------------------
#
# Here we define the physics of the problem. The data consists of apparent
# resistivity values. This is defined here.
#

simulation = dc.simulation_1d.Simulation1DLayers(
    survey=survey,
    rhoMap=resistivity_map,
    thicknessesMap=layer_map,
    data_type="apparent_resistivity",
Exemple #18
0
def run(plotIt=True):

    cs, ncx, ncz, npad = 5.0, 25, 15, 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 < 0.0) & (mesh.vectorCCz >= -100.0)
    actMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap
    sig_half = 2e-3
    sig_air = 1e-8
    sig_layer = 1e-3
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer
    mtrue = np.log(sigma[active])

    rxOffset = 1e-3
    rx = time_domain.Rx.PointMagneticFluxTimeDerivative(
        np.array([[rxOffset, 0.0, 30]]), np.logspace(-5, -3, 31), "z"
    )
    src = time_domain.Src.MagDipole([rx], location=np.array([0.0, 0.0, 80]))
    survey = time_domain.Survey([src])
    time_steps = [(1e-06, 20), (1e-05, 20), (0.0001, 20)]
    simulation = time_domain.Simulation3DElectricField(
        mesh, sigmaMap=mapping, survey=survey, time_steps=time_steps
    )
    # d_true = simulation.dpred(mtrue)

    # create observed data
    rel_err = 0.05
    data = simulation.make_synthetic_data(mtrue, relative_error=rel_err)

    dmisfit = data_misfit.L2DataMisfit(simulation=simulation, data=data)
    regMesh = discretize.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = regularization.Tikhonov(regMesh, alpha_s=1e-2, alpha_x=1.0)
    opt = optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)

    # Create an inversion object
    beta = directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    inv = inversion.BaseInversion(invProb, directiveList=[beta, betaest])
    m0 = np.log(np.ones(mtrue.size) * sig_half)
    simulation.counter = opt.counter = utils.Counter()
    opt.remember("xc")

    mopt = inv.run(m0)

    if plotIt:
        fig, ax = plt.subplots(1, 2, figsize=(10, 6))
        ax[0].loglog(rx.times, -invProb.dpred, "b.-")
        ax[0].loglog(rx.times, -data.dobs, "r.-")
        ax[0].legend(("Noisefree", "$d^{obs}$"), fontsize=16)
        ax[0].set_xlabel("Time (s)", fontsize=14)
        ax[0].set_ylabel("$B_z$ (T)", 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-2)
        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 run(runIt=False, plotIt=True, saveIt=False, saveFig=False, cleanup=True):
    """
    Run the bookpurnong 1D stitched RESOLVE inversions.

    :param bool runIt: re-run the inversions? Default downloads and plots saved results
    :param bool plotIt: show the plots?
    :param bool saveIt: save the re-inverted results?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """

    # download the data
    downloads, directory = download_and_unzip_data()

    # Load resolve data
    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")

    river_path = resolve["river_path"][()]  # River path
    nSounding = resolve["data"].shape[0]  # the # of soundings

    # Bird height from surface
    b_height_resolve = resolve["src_elevation"][()]

    # fetch the frequencies we are considering
    cpi_inds = [0, 2, 6, 8, 10]  # Indices for HCP in-phase
    cpq_inds = [1, 3, 7, 9, 11]  # Indices for HCP quadrature
    frequency_cp = resolve["frequency_cp"][()]

    # build a mesh
    cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.0), np.log10(12.0), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = discretize.CylMesh([hx, 1, hz], "00C")
    active = mesh.vectorCCz < 0.0

    # survey parameters
    rxOffset = 7.86  # tx-rx separation
    bp = -mu_0 / (4 * np.pi * rxOffset**3)  # primary magnetic field

    # re-run the inversion
    if runIt:

        # set up the mappings - we are inverting for 1D log conductivity
        # below the earth's surface.
        actMap = maps.InjectActiveCells(mesh,
                                        active,
                                        np.log(1e-8),
                                        nC=mesh.nCz)
        mapping = maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * actMap

        # build starting and reference model
        sig_half = 1e-1
        sig_air = 1e-8
        sigma = np.ones(mesh.nCz) * sig_air
        sigma[active] = sig_half
        m0 = np.log(1e-1) * np.ones(active.sum())  # starting model
        mref = np.log(1e-1) * np.ones(active.sum())  # reference model

        # initalize empty lists for storing inversion results
        mopt_re = []  # recovered model
        dpred_re = []  # predicted data
        dobs_re = []  # observed data

        # downsample the data for the inversion
        nskip = 40

        # set up a noise model
        # 10% for the 3 lowest frequencies, 15% for the two highest
        relative = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
        floor = abs(20 * bp * 1e-6)  # floor of 20ppm

        # loop over the soundings and invert each
        for rxind in range(nSounding):

            # convert data from ppm to magnetic field (A/m^2)
            dobs = (np.c_[resolve["data"][rxind, :][cpi_inds].astype(float),
                          resolve["data"][
                              rxind, :][cpq_inds].astype(float), ].flatten() *
                    bp * 1e-6)

            # perform the inversion
            src_height = b_height_resolve[rxind].astype(float)
            mopt, dpred, dobs = resolve_1Dinversions(
                mesh,
                dobs,
                src_height,
                frequency_cp,
                m0,
                mref,
                mapping,
                relative=relative,
                floor=floor,
            )

            # add results to our list
            mopt_re.append(mopt)
            dpred_re.append(dpred)
            dobs_re.append(dobs)

        # save results
        mopt_re = np.vstack(mopt_re)
        dpred_re = np.vstack(dpred_re)
        dobs_re = np.vstack(dobs_re)

        if saveIt:
            np.save("mopt_re_final", mopt_re)
            np.save("dobs_re_final", dobs_re)
            np.save("dpred_re_final", dpred_re)

    mopt_re = resolve["mopt"][()]
    dobs_re = resolve["dobs"][()]
    dpred_re = resolve["dpred"][()]

    sigma = np.exp(mopt_re)
    indz = -7  # depth index

    # so that we can visually compare with literature (eg Viezzoli, 2010)
    cmap = "jet"

    # dummy figure for colobar
    fig = plt.figure()
    out = plt.scatter(np.ones(3),
                      np.ones(3),
                      c=np.linspace(-2, 1, 3),
                      cmap=cmap)
    plt.close(fig)

    # plot from the paper
    fs = 13  # fontsize
    # matplotlib.rcParams['font.size'] = fs
    plt.figure(figsize=(13, 7))
    ax0 = plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2)
    ax1 = plt.subplot2grid((2, 3), (0, 2))
    ax2 = plt.subplot2grid((2, 3), (1, 2))

    # titles of plots
    title = [
        ("(a) Recovered model, %.1f m depth") %
        (-mesh.vectorCCz[active][indz]),
        "(b) Obs (Real 400 Hz)",
        "(c) Pred (Real 400 Hz)",
    ]

    temp = sigma[:, indz]
    tree = cKDTree(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])))
    d, d_inds = tree.query(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])),
                           k=20)
    w = 1.0 / (d + 100.0)**2.0
    w = utils.sdiag(1.0 / np.sum(w, axis=1)) * (w)
    xy = resolve["xy"]
    temp = (temp.flatten()[d_inds] * w).sum(axis=1)
    utils.plot2Ddata(
        xy,
        temp,
        ncontour=100,
        scale="log",
        dataloc=False,
        contourOpts={
            "cmap": cmap,
            "vmin": 1e-2,
            "vmax": 1e1
        },
        ax=ax0,
    )
    ax0.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], "k.", alpha=0.02, ms=1)

    cb = plt.colorbar(out,
                      ax=ax0,
                      ticks=np.linspace(-2, 1, 4),
                      format="$10^{%.1f}$")
    cb.set_ticklabels(["0.01", "0.1", "1", "10"])
    cb.set_label("Conductivity (S/m)")
    ax0.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)

    # plot observed and predicted data
    freq_ind = 0
    axs = [ax1, ax2]
    temp_dobs = dobs_re[:, freq_ind].copy()
    ax1.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)
    inf = temp_dobs / abs(bp) * 1e6
    print(inf.min(), inf.max())
    out = utils.plot2Ddata(
        resolve["xy"][()],
        temp_dobs / abs(bp) * 1e6,
        ncontour=100,
        scale="log",
        dataloc=False,
        ax=ax1,
        contourOpts={"cmap": "viridis"},
    )
    vmin, vmax = out[0].get_clim()
    print(vmin, vmax)
    cb = plt.colorbar(
        out[0],
        ticks=np.logspace(np.log10(vmin), np.log10(vmax), 3),
        ax=ax1,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb.set_label("Bz (ppm)")
    temp_dpred = dpred_re[:, freq_ind].copy()
    # temp_dpred[mask_:_data] = np.nan
    ax2.plot(river_path[:, 0], river_path[:, 1], "k-", lw=0.5)
    utils.plot2Ddata(
        resolve["xy"][()],
        temp_dpred / abs(bp) * 1e6,
        ncontour=100,
        scale="log",
        dataloc=False,
        contourOpts={
            "vmin": vmin,
            "vmax": vmax,
            "cmap": "viridis"
        },
        ax=ax2,
    )
    cb = plt.colorbar(
        out[0],
        ticks=np.logspace(np.log10(vmin), np.log10(vmax), 3),
        ax=ax2,
        format="%.1e",
        fraction=0.046,
        pad=0.04,
    )
    cb.set_label("Bz (ppm)")

    for i, ax in enumerate([ax0, ax1, ax2]):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        xloc, yloc = 462100.0, 6196500.0
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        # ax.plot(xloc, yloc, 'wo')
        ax.plot(river_path[:, 0], river_path[:, 1], "k", lw=0.5)

        ax.set_aspect("equal")
        ax.plot(resolve["xy"][:, 0],
                resolve["xy"][:, 1],
                "k.",
                alpha=0.02,
                ms=1)

        ax.set_yticklabels([str(f) for f in yticks])
        ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])

    plt.tight_layout()

    if plotIt:
        plt.show()

    if saveFig is True:
        fig.savefig("obspred_resolve.png", dpi=200)

    resolve.close()
    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)
Exemple #20
0
    def test_io_rhoa(self):
        # Setup a dipole-dipole Survey

        for survey_type, test_file, rhoa_file in zip(
            ["dipole-dipole", "pole-dipole", "dipole-pole", "pole-pole"],
            [
                "2sph_dipole_dipole.obs",
                "2sph_pole_dipole.obs",
                "2sph_dipole_pole.obs",
                "2sph_pole_pole.obs",
            ],
            [
                "rhoA_GIF_dd.txt",
                "rhoA_GIF_pd.txt",
                "rhoA_GIF_dp.txt",
                "rhoA_GIF_pp.txt",
            ],
        ):
            print("\n Testing {} ... ".format(survey_type))
            survey = utils.gen_DCIPsurvey(
                self.xyz,
                survey_type=survey_type,
                dim=self.mesh.dim,
                a=self.survey_a,
                b=self.survey_b,
                n=self.survey_n,
            )

            self.assertEqual(survey_type, survey.survey_type)

            # Setup Problem with exponential mapping
            expmap = maps.ExpMap(self.mesh)
            problem = dc.Simulation3DCellCentered(
                self.mesh, sigmaMap=expmap, survey=survey, bc_type="Neumann"
            )
            problem.solver = Solver

            # Create synthetic data
            dobs = problem.make_synthetic_data(self.model, relative_error=0.0)
            dobs.eps = 1e-5

            # Testing IO
            surveyfile = os.path.sep.join([self.basePath, test_file])
            utils.writeUBC_DCobs(
                surveyfile, dobs, survey_type=survey_type, dim=3, format_type="GENERAL"
            )
            data2 = utils.readUBC_DC3Dobs(surveyfile)
            self.assertTrue(np.allclose(mkvc(data2), mkvc(dobs)))

            if self.plotIt:
                import matplotlib.pyplot as plt

                # Test Pseudosections plotting
                fig, ax = plt.subplots(1, 1, figsize=(15, 3))
                ax = utils.plot_pseudoSection(
                    survey,
                    ax,
                    survey_type=survey_type,
                    scale="log",
                    clim=None,
                    data_type="appResistivity",
                    pcolorOpts={"cmap": "viridis"},
                    data_location=True,
                )
                plt.show()

            # Test the utils functions electrode_separations,
            # source_receiver_midpoints, geometric_factor,
            # apparent_resistivity all at once
            rhoapp = utils.apparent_resistivity(
                dobs, survey_type=survey_type, space_type="half-space", eps=0.0
            )

            rhoA_GIF_file = os.path.sep.join([self.basePath, rhoa_file])
            rhoA_GIF = np.loadtxt(rhoA_GIF_file)
            passed = np.allclose(rhoapp, rhoA_GIF)
            self.assertTrue(passed)
            print("   ... ok \n".format(survey_type))
Exemple #21
0
def get_mapping(mesh):
    active = mesh.vectorCCz < 0.0
    activeMap = maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    return maps.ExpMap(mesh) * maps.SurjectVertical1D(mesh) * activeMap
Exemple #22
0
def run(plotIt=True, survey_type="dipole-dipole", p=0.0, qx=2.0, qz=2.0):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0.0, 200.0
    ymin, ymax = 0.0, 0.0
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = gen_DCIPsurvey(endl,
                            survey_type=survey_type,
                            dim=2,
                            a=10,
                            b=10,
                            n=10)
    survey = IO.from_abmn_locations_to_survey(
        survey.locations_a,
        survey.locations_b,
        survey.locations_m,
        survey.locations_n,
        survey_type,
        data_dc_type="volt",
    )

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = genTopography(mesh, -10, 0, its=100)
    actind = utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey.drape_electrodes_on_topography(mesh, actind, option="top")

    # Build a conductivity model
    blk_inds_c = utils.model_builder.getIndicesSphere(np.r_[60.0, -25.0], 12.5,
                                                      mesh.gridCC)
    blk_inds_r = utils.model_builder.getIndicesSphere(np.r_[140.0, -25.0],
                                                      12.5, mesh.gridCC)
    layer_inds = mesh.gridCC[:, 1] > -5.0
    sigma = np.ones(mesh.nC) * 1.0 / 100.0
    sigma[blk_inds_c] = 1.0 / 10.0
    sigma[blk_inds_r] = 1.0 / 1000.0
    sigma[~actind] = 1.0 / 1e8
    rho = 1.0 / sigma

    # Show the true conductivity model
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(
            temp,
            grid=True,
            ax=ax,
            gridOpts={"alpha": 0.2},
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
        )
        ax.plot(survey.electrode_locations[:, 0],
                survey.electrode_locations[:, 1], "k.")
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Resistivity (ohm-m)")
        ax.set_aspect("equal")
        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    mapping = maps.ExpMap(mesh) * actmap

    # Generate mtrue
    mtrue = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Simulation2DNodal(mesh,
                               survey=survey,
                               rhoMap=mapping,
                               storeJ=True,
                               Solver=Solver,
                               verbose=True)

    # Make synthetic DC data with 5% Gaussian noise
    data = prb.make_synthetic_data(mtrue, relative_error=0.05, add_noise=True)

    IO.data_dc = data.dobs
    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(data=data.dobs / IO.G,
                             data_type="apparent_resistivity")

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(data.dobs / IO.G, bins=20)
        plt.xlabel("Apparent Resisitivty ($\Omega$m)")
        plt.show()

    # Set initial model based upon histogram
    m0 = np.ones(actmap.nP) * np.log(100.0)

    # Set standard_deviation
    # floor
    eps = 10**(-3.2)
    # percentage
    relative = 0.05
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data)
    uncert = abs(data.dobs) * relative + eps
    dmisfit.standard_deviation = uncert

    # Map for a regularization
    regmap = maps.IdentityMap(nP=int(actind.sum()))

    # Related to inversion
    reg = regularization.Sparse(mesh,
                                indActive=actind,
                                mapping=regmap,
                                gradientType="components")
    #     gradientType = 'components'
    reg.norms = np.c_[p, qx, qz, 0.0]
    IRLS = directives.Update_IRLS(max_irls_iterations=20,
                                  minGNiter=1,
                                  beta_search=False,
                                  fix_Jmatrix=True)

    opt = optimization.InexactGaussNewton(maxIter=40)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)
    beta = directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = directives.TargetMisfit()
    update_Jacobi = directives.UpdatePreconditioner()
    inv = inversion.BaseInversion(invProb, directiveList=[betaest, IRLS])
    prb.counter = opt.counter = utils.Counter()
    opt.LSshorten = 0.5
    opt.remember("xc")

    # Run inversion
    mopt = inv.run(m0)

    rho_est = mapping * mopt
    rho_est_l2 = mapping * invProb.l2model
    rho_est[~actind] = np.nan
    rho_est_l2[~actind] = np.nan
    rho_true = rho.copy()
    rho_true[~actind] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(3, 1, figsize=(20, 9))
        out1 = mesh.plotImage(
            rho_true,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[0],
        )
        out2 = mesh.plotImage(
            rho_est_l2,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[1],
        )
        out3 = mesh.plotImage(
            rho_est,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[2],
        )

        out = [out1, out2, out3]
        titles = ["True", "L2", ("L%d, Lx%d, Lz%d") % (p, qx, qz)]
        for i in range(3):
            ax[i].plot(survey.electrode_locations[:, 0],
                       survey.electrode_locations[:, 1], "kv")
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect("equal")
            ax[i].set_title(titles[i])
        plt.tight_layout()
        plt.show()
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)
Exemple #24
0
def run(
    plotIt=True,
    survey_type="dipole-dipole",
    rho_background=1e3,
    rho_block=1e2,
    block_x0=100,
    block_dx=10,
    block_y0=-10,
    block_dy=5,
):

    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0.0, 200.0
    ymin, ymax = 0.0, 0.0
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DCutils.gen_DCIPsurvey(endl,
                                    survey_type=survey_type,
                                    dim=2,
                                    a=10,
                                    b=10,
                                    n=10)
    survey = IO.from_ambn_locations_to_survey(
        survey.locations_a,
        survey.locations_b,
        survey.locations_m,
        survey.locations_n,
        survey_type,
        data_dc_type="volt",
    )

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    # Flat topography
    actind = utils.surface2ind_topo(
        mesh, np.c_[mesh.vectorCCx, mesh.vectorCCx * 0.0])
    survey.drape_electrodes_on_topography(mesh, actind, option="top")
    # Use Exponential Map: m = log(rho)
    actmap = maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    parametric_block = maps.ParametricBlock(mesh, slopeFact=1e2)
    mapping = maps.ExpMap(mesh) * parametric_block
    # Set true model
    # val_background,val_block, block_x0, block_dx, block_y0, block_dy
    mtrue = np.r_[np.log(1e3), np.log(10), 100, 10, -20, 10]

    # Set initial model
    m0 = np.r_[np.log(rho_background),
               np.log(rho_block), block_x0, block_dx, block_y0, block_dy, ]
    rho = mapping * mtrue
    rho0 = mapping * m0
    # Show the true conductivity model
    fig = plt.figure(figsize=(12, 3))
    ax = plt.subplot(111)
    temp = rho.copy()
    temp[~actind] = np.nan
    out = mesh.plotImage(
        temp,
        grid=False,
        ax=ax,
        gridOpts={"alpha": 0.2},
        clim=(10, 1000),
        pcolorOpts={
            "cmap": "viridis",
            "norm": colors.LogNorm()
        },
    )
    ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1],
            "k.")
    ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
    ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
    cb = plt.colorbar(out[0])
    cb.set_label("Resistivity (ohm-m)")
    ax.set_aspect("equal")
    ax.set_title("True resistivity model")
    plt.show()
    # Show the true conductivity model
    fig = plt.figure(figsize=(12, 3))
    ax = plt.subplot(111)
    temp = rho0.copy()
    temp[~actind] = np.nan
    out = mesh.plotImage(
        temp,
        grid=False,
        ax=ax,
        gridOpts={"alpha": 0.2},
        clim=(10, 1000),
        pcolorOpts={
            "cmap": "viridis",
            "norm": colors.LogNorm()
        },
    )
    ax.plot(survey.electrode_locations[:, 0], survey.electrode_locations[:, 1],
            "k.")
    ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
    ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
    cb = plt.colorbar(out[0])
    cb.set_label("Resistivity (ohm-m)")
    ax.set_aspect("equal")
    ax.set_title("Initial resistivity model")
    plt.show()

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Simulation2DNodal(mesh,
                               survey=survey,
                               rhoMap=mapping,
                               storeJ=True,
                               solver=Solver)

    # Make synthetic DC data with 5% Gaussian noise
    data = prb.make_synthetic_data(mtrue, relative_error=0.05, add_noise=True)

    # Show apparent resisitivty pseudo-section
    IO.plotPseudoSection(data=data.dobs / IO.G,
                         data_type="apparent_resistivity")

    # Show apparent resisitivty histogram
    fig = plt.figure()
    out = hist(data.dobs / IO.G, bins=20)
    plt.show()
    # Set standard_deviation
    # floor
    eps = 10**(-3.2)
    # percentage
    relative = 0.05
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data)
    uncert = abs(data.dobs) * relative + eps
    dmisfit.standard_deviation = uncert

    # Map for a regularization
    mesh_1d = discretize.TensorMesh([parametric_block.nP])
    # Related to inversion
    reg = regularization.Simple(mesh_1d, alpha_x=0.0)
    opt = optimization.InexactGaussNewton(maxIter=10)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)
    beta = directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = directives.TargetMisfit()
    updateSensW = directives.UpdateSensitivityWeights()
    update_Jacobi = directives.UpdatePreconditioner()
    invProb.beta = 0.0
    inv = inversion.BaseInversion(invProb, directiveList=[target])
    prb.counter = opt.counter = utils.Counter()
    opt.LSshorten = 0.5
    opt.remember("xc")

    # Run inversion
    mopt = inv.run(m0)

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping * mopt
    rho_true = rho.copy()
    # show recovered conductivity
    vmin, vmax = rho.min(), rho.max()
    fig, ax = plt.subplots(2, 1, figsize=(20, 6))
    out1 = mesh.plotImage(
        rho_true,
        clim=(10, 1000),
        pcolorOpts={
            "cmap": "viridis",
            "norm": colors.LogNorm()
        },
        ax=ax[0],
    )
    out2 = mesh.plotImage(
        rho_est,
        clim=(10, 1000),
        pcolorOpts={
            "cmap": "viridis",
            "norm": colors.LogNorm()
        },
        ax=ax[1],
    )
    out = [out1, out2]
    for i in range(2):
        ax[i].plot(survey.electrode_locations[:, 0],
                   survey.electrode_locations[:, 1], "kv")
        ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[i][0], ax=ax[i])
        cb.set_label("Resistivity ($\Omega$m)")
        ax[i].set_xlabel("Northing (m)")
        ax[i].set_ylabel("Elevation (m)")
        ax[i].set_aspect("equal")
    ax[0].set_title("True resistivity model")
    ax[1].set_title("Recovered resistivity model")
    plt.tight_layout()
    plt.show()
def run(plotIt=True, survey_type="dipole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0.0, 200.0
    ymin, ymax = 0.0, 0.0
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = gen_DCIPsurvey(endl,
                            survey_type=survey_type,
                            dim=2,
                            a=10,
                            b=10,
                            n=10)
    survey = IO.from_ambn_locations_to_survey(
        survey.locations_a,
        survey.locations_b,
        survey.locations_m,
        survey.locations_n,
        survey_type,
        data_dc_type="volt",
    )

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = genTopography(mesh, -10, 0, its=100)
    actind = utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey.drape_electrodes_on_topography(mesh, actind, option="top")

    # Build a conductivity model
    blk_inds_c = utils.model_builder.getIndicesSphere(np.r_[60.0, -25.0], 12.5,
                                                      mesh.gridCC)
    blk_inds_r = utils.model_builder.getIndicesSphere(np.r_[140.0, -25.0],
                                                      12.5, mesh.gridCC)
    layer_inds = mesh.gridCC[:, 1] > -5.0
    sigma = np.ones(mesh.nC) * 1.0 / 100.0
    sigma[blk_inds_c] = 1.0 / 10.0
    sigma[blk_inds_r] = 1.0 / 1000.0
    sigma[~actind] = 1.0 / 1e8
    rho = 1.0 / sigma

    # Show the true conductivity model
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(
            temp,
            grid=True,
            ax=ax,
            gridOpts={"alpha": 0.2},
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
        )
        ax.plot(survey.electrode_locations[:, 0],
                survey.electrode_locations[:, 1], "k.")
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Resistivity (ohm-m)")
        ax.set_aspect("equal")
        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    mapping = maps.ExpMap(mesh) * actmap

    # Generate mtrue
    mtrue = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Simulation2DNodal(mesh,
                               survey=survey,
                               rhoMap=mapping,
                               storeJ=True,
                               Solver=Solver,
                               verbose=True)

    geometric_factor = survey.set_geometric_factor(
        data_type="apparent_resistivity",
        survey_type="dipole-dipole",
        space_type="half-space",
    )

    # Make synthetic DC data with 5% Gaussian noise
    data = prb.make_synthetic_data(mtrue, relative_error=0.05, add_noise=True)

    IO.data_dc = data.dobs
    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(data=data.dobs, data_type="apparent_resistivity")

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(data.dobs, bins=20)
        plt.xlabel("Apparent Resisitivty ($\Omega$m)")
        plt.show()

    # Set initial model based upon histogram
    m0 = np.ones(actmap.nP) * np.log(100.0)

    # Set standard_deviation
    # floor (10 ohm-m)
    eps = 1.0
    # percentage
    relative = 0.05
    dmisfit = data_misfit.L2DataMisfit(simulation=prb, data=data)
    uncert = abs(data.dobs) * relative + eps
    dmisfit.standard_deviation = uncert

    # Map for a regularization
    regmap = maps.IdentityMap(nP=int(actind.sum()))

    # Related to inversion
    reg = regularization.Sparse(mesh, indActive=actind, mapping=regmap)
    opt = optimization.InexactGaussNewton(maxIter=15)
    invProb = inverse_problem.BaseInvProblem(dmisfit, reg, opt)
    beta = directives.BetaSchedule(coolingFactor=5, coolingRate=2)
    betaest = directives.BetaEstimate_ByEig(beta0_ratio=1e0)
    target = directives.TargetMisfit()
    updateSensW = directives.UpdateSensitivityWeights()
    update_Jacobi = directives.UpdatePreconditioner()
    inv = inversion.BaseInversion(
        invProb,
        directiveList=[beta, target, updateSensW, betaest, update_Jacobi])
    prb.counter = opt.counter = utils.Counter()
    opt.LSshorten = 0.5
    opt.remember("xc")

    # Run inversion
    mopt = inv.run(m0)

    # Get diag(JtJ)
    mask_inds = np.ones(mesh.nC, dtype=bool)
    jtj = np.sqrt(updateSensW.JtJdiag[0])
    jtj /= jtj.max()
    temp = np.ones_like(jtj, dtype=bool)
    temp[jtj > 0.005] = False
    mask_inds[actind] = temp
    actind_final = np.logical_and(actind, ~mask_inds)
    jtj_cc = np.ones(mesh.nC) * np.nan
    jtj_cc[actind] = jtj

    # Show the sensitivity
    if plotIt:
        fig = plt.figure(figsize=(12, 3))
        ax = plt.subplot(111)
        temp = rho.copy()
        temp[~actind] = np.nan
        out = mesh.plotImage(
            jtj_cc,
            grid=True,
            ax=ax,
            gridOpts={"alpha": 0.2},
            clim=(0.005, 0.5),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
        )
        ax.plot(survey.electrode_locations[:, 0],
                survey.electrode_locations[:, 1], "k.")
        ax.set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
        ax.set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
        cb = plt.colorbar(out[0])
        cb.set_label("Sensitivity")
        ax.set_aspect("equal")
        plt.show()

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping * mopt
    rho_est[~actind_final] = np.nan
    rho_true = rho.copy()
    rho_true[~actind_final] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(
            rho_true,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[0],
        )
        out2 = mesh.plotImage(
            rho_est,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[1],
        )
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(survey.electrode_locations[:, 0],
                       survey.electrode_locations[:, 1], "kv")
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect("equal")
        plt.tight_layout()
        plt.show()
def run(plotIt=True, survey_type="dipole-dipole"):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0.0, 200.0
    ymin, ymax = 0.0, 0.0
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey_dc = gen_DCIPsurvey(endl,
                               survey_type=survey_type,
                               dim=2,
                               a=10,
                               b=10,
                               n=10)
    survey_dc = IO.from_abmn_locations_to_survey(
        survey_dc.locations_a,
        survey_dc.locations_b,
        survey_dc.locations_m,
        survey_dc.locations_n,
        survey_type,
        data_dc_type="volt",
        data_ip_type="volt",
    )

    # Obtain 2D TensorMesh
    mesh, actind = IO.set_mesh()
    topo, mesh1D = genTopography(mesh, -10, 0, its=100)
    actind = utils.surface2ind_topo(mesh, np.c_[mesh1D.vectorCCx, topo])
    survey_dc.drape_electrodes_on_topography(mesh, actind, option="top")

    # Build conductivity and chargeability model
    blk_inds_c = utils.model_builder.getIndicesSphere(np.r_[60.0, -25.0], 12.5,
                                                      mesh.gridCC)
    blk_inds_r = utils.model_builder.getIndicesSphere(np.r_[140.0, -25.0],
                                                      12.5, mesh.gridCC)
    blk_inds_charg = utils.model_builder.getIndicesSphere(
        np.r_[100.0, -25], 12.5, mesh.gridCC)
    sigma = np.ones(mesh.nC) * 1.0 / 100.0
    sigma[blk_inds_c] = 1.0 / 10.0
    sigma[blk_inds_r] = 1.0 / 1000.0
    sigma[~actind] = 1.0 / 1e8
    rho = 1.0 / sigma
    charg = np.zeros(mesh.nC)
    charg[blk_inds_charg] = 0.1

    # Show the true conductivity model
    if plotIt:
        fig, axs = plt.subplots(2, 1, figsize=(12, 6))
        temp_rho = rho.copy()
        temp_rho[~actind] = np.nan
        temp_charg = charg.copy()
        temp_charg[~actind] = np.nan

        out1 = mesh.plotImage(
            temp_rho,
            grid=True,
            ax=axs[0],
            gridOpts={"alpha": 0.2},
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
        )
        out2 = mesh.plotImage(
            temp_charg,
            grid=True,
            ax=axs[1],
            gridOpts={"alpha": 0.2},
            clim=(0, 0.1),
            pcolorOpts={"cmap": "magma"},
        )
        for i in range(2):
            axs[i].plot(
                survey_dc.electrode_locations[:, 0],
                survey_dc.electrode_locations[:, 1],
                "kv",
            )
            axs[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            axs[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            axs[i].set_aspect("equal")
        cb = plt.colorbar(out1[0], ax=axs[0])
        cb.set_label("Resistivity (ohm-m)")
        cb = plt.colorbar(out2[0], ax=axs[1])
        cb.set_label("Chargeability")

        plt.show()

    # Use Exponential Map: m = log(rho)
    actmap = maps.InjectActiveCells(mesh,
                                    indActive=actind,
                                    valInactive=np.log(1e8))
    mapping = maps.ExpMap(mesh) * actmap

    # Generate mtrue_dc for resistivity
    mtrue_dc = np.log(rho[actind])

    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    prb = DC.Simulation2DNodal(mesh,
                               survey=survey_dc,
                               rhoMap=mapping,
                               storeJ=True,
                               solver=Solver)

    # Make synthetic DC data with 5% Gaussian noise
    data_dc = prb.make_synthetic_data(mtrue_dc,
                                      relative_error=0.05,
                                      add_noise=True)
    IO.data_dc = data_dc.dobs

    # Generate mtrue_ip for chargability
    mtrue_ip = charg[actind]
    # Generate 2.5D DC problem
    # "N" means potential is defined at nodes
    survey_ip = IP.from_dc_to_ip_survey(survey_dc, dim="2.5D")
    prb_ip = IP.Simulation2DNodal(mesh,
                                  survey=survey_ip,
                                  etaMap=actmap,
                                  storeJ=True,
                                  rho=rho,
                                  solver=Solver)

    data_ip = prb_ip.make_synthetic_data(mtrue_ip,
                                         relative_error=0.05,
                                         add_noise=True)

    IO.data_ip = data_ip.dobs

    # Show apparent resisitivty pseudo-section
    if plotIt:
        IO.plotPseudoSection(data_type="apparent_resistivity",
                             scale="log",
                             cmap="viridis")
        plt.show()

    # Show apparent chargeability pseudo-section
    if plotIt:
        IO.plotPseudoSection(data_type="apparent_chargeability",
                             scale="linear",
                             cmap="magma")
        plt.show()

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure(figsize=(10, 4))
        ax1 = plt.subplot(121)
        out = hist(np.log10(abs(IO.voltages)), bins=20)
        ax1.set_xlabel("log10 DC voltage (V)")
        ax2 = plt.subplot(122)
        out = hist(IO.apparent_resistivity, bins=20)
        ax2.set_xlabel("Apparent Resistivity ($\Omega$m)")
        plt.tight_layout()
        plt.show()

    # Set initial model based upon histogram
    m0_dc = np.ones(actmap.nP) * np.log(100.0)
    # Set standard deviation
    # floor
    data_dc.noise_floor = 10**(-3.2)
    # percentage
    data_dc.relative_error = 0.05

    mopt_dc, pred_dc = DC.run_inversion(m0_dc,
                                        prb,
                                        data_dc,
                                        actind,
                                        mesh,
                                        beta0_ratio=1e0,
                                        use_sensitivity_weight=True)

    # Convert obtained inversion model to resistivity
    # rho = M(m), where M(.) is a mapping

    rho_est = mapping * mopt_dc
    rho_est[~actind] = np.nan
    rho_true = rho.copy()
    rho_true[~actind] = np.nan

    # show recovered conductivity
    if plotIt:
        vmin, vmax = rho.min(), rho.max()
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(
            rho_true,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[0],
        )
        out2 = mesh.plotImage(
            rho_est,
            clim=(10, 1000),
            pcolorOpts={
                "cmap": "viridis",
                "norm": colors.LogNorm()
            },
            ax=ax[1],
        )
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(
                survey_dc.electrode_locations[:, 0],
                survey_dc.electrode_locations[:, 1],
                "kv",
            )
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect("equal")
        plt.tight_layout()
        plt.show()

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure(figsize=(10, 4))
        ax1 = plt.subplot(121)
        out = hist(np.log10(abs(IO.voltages_ip)), bins=20)
        ax1.set_xlabel("log10 IP voltage (V)")
        ax2 = plt.subplot(122)
        out = hist(IO.apparent_chargeability, bins=20)
        ax2.set_xlabel("Apparent Chargeability (V/V)")
        plt.tight_layout()
        plt.show()

    # Set initial model based upon histogram
    m0_ip = np.ones(actmap.nP) * 1e-10
    # Set standard deviation
    # floor
    data_ip.noise_floor = 10**(-4)
    # percentage
    data_ip.relative_error = 0.05
    # Clean sensitivity function formed with true resistivity
    prb_ip._Jmatrix = None
    # Input obtained resistivity to form sensitivity
    prb_ip.rho = mapping * mopt_dc
    mopt_ip, _ = IP.run_inversion(
        m0_ip,
        prb_ip,
        data_ip,
        actind,
        mesh,
        upper=np.Inf,
        lower=0.0,
        beta0_ratio=1e0,
        use_sensitivity_weight=True,
    )

    # Convert obtained inversion model to chargeability
    # charg = M(m), where M(.) is a mapping for cells below topography

    charg_est = actmap * mopt_ip
    charg_est[~actind] = np.nan
    charg_true = charg.copy()
    charg_true[~actind] = np.nan

    # show recovered chargeability
    if plotIt:
        fig, ax = plt.subplots(2, 1, figsize=(20, 6))
        out1 = mesh.plotImage(charg_true,
                              clim=(0, 0.1),
                              pcolorOpts={"cmap": "magma"},
                              ax=ax[0])
        out2 = mesh.plotImage(charg_est,
                              clim=(0, 0.1),
                              pcolorOpts={"cmap": "magma"},
                              ax=ax[1])
        out = [out1, out2]
        for i in range(2):
            ax[i].plot(
                survey_dc.electrode_locations[:, 0],
                survey_dc.electrode_locations[:, 1],
                "rv",
            )
            ax[i].set_xlim(IO.grids[:, 0].min(), IO.grids[:, 0].max())
            ax[i].set_ylim(-IO.grids[:, 1].max(), IO.grids[:, 1].min())
            cb = plt.colorbar(out[i][0], ax=ax[i])
            cb.set_label("Resistivity ($\Omega$m)")
            ax[i].set_xlabel("Northing (m)")
            ax[i].set_ylabel("Elevation (m)")
            ax[i].set_aspect("equal")
        plt.tight_layout()
        plt.show()
Exemple #27
0
# mesh
csx, ncx, npadx = 25.0, 16, 10
csz, ncz, npadz = 25.0, 8, 10
pf = 1.5

# primary mesh
hx = [(csx, ncx), (csx, npadx, pf)]
hz = [(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)]
meshp = discretize.CylMesh([hx, 1.0, hz], x0="0CC")

# secondary mesh
h = [(csz, npadz - 4, -pf), (csz, ncz), (csz, npadz - 4, pf)]
meshs = discretize.TensorMesh(3 * [h], x0="CCC")

# mappings
primaryMapping = (maps.ExpMap(meshp) * maps.SurjectFull(meshp) *
                  maps.Projection(nP=8, index=[0]))

mapping = (
    maps.ExpMap(meshs) * maps.ParametricBlockInLayer(meshs) *
    maps.Projection(nP=8, index=np.hstack([np.r_[0], np.arange(0, 8)])))

primaryMap2Meshs = (maps.ExpMap(meshs) * maps.SurjectFull(meshs) *
                    maps.Projection(nP=8, index=[0]))


class PrimSecFDEMTest(object):

    # --------------------- Run some tests! --------------------- #
    def DataTest(self):
        print("\nTesting Data")
Exemple #28
0
# Mappings are used to take the inversion model and represent it as electrical
# conductivity on the inversion mesh. We will invert for log-conductivity below
# the surface, fixing the conductivity of the air cells to 1e-8 S/m

# create a 2D mesh that includes air cells
mesh2D = discretize.TensorMesh([mesh.hx, mesh.hz], x0=mesh.x0[[0, 2]])
active_inds = mesh2D.gridCC[:, 1] < 0  # active indices are below the surface


mapping = (
    maps.Surject2Dto3D(mesh)
    * maps.InjectActiveCells(  # populates 3D space from a 2D model
        mesh2D, active_inds, sigma_air
    )
    * maps.ExpMap(  # adds air cells
        nP=inversion_mesh.nC
    )  # takes the exponential (log(sigma) --> sigma)
)

###############################################################################
# True Model
# ----------
#
# Create our true model which we will use to generate synthetic data for

m_true = np.log(sigma_deep) * np.ones(inversion_mesh.nC)
interface_depth = interface(inversion_mesh.gridCC[:, 0])
m_true[inversion_mesh.gridCC[:, 1] > interface_depth] = np.log(sigma_surface)

fig, ax = plt.subplots(1, 1)
cb = plt.colorbar(inversion_mesh.plotImage(m_true, ax=ax, grid=True)[0], ax=ax)
Exemple #29
0
# well as the mapping from the model space to the active cells. Starting and
# reference models can be a constant background value or contain a-priori
# structures. Here, the starting model is the natural log of 0.01 S/m.
#
#

# Define conductivity model in S/m (or resistivity model in Ohm m)
air_conductivity = np.log(1e-8)
background_conductivity = np.log(1e-2)

# Define the mapping from active cells to the entire domain
active_map = maps.InjectActiveCells(mesh, ind_active, np.exp(air_conductivity))
nC = int(ind_active.sum())

# Define the mapping from the model to the conductivity of the entire domain
conductivity_map = active_map * maps.ExpMap()

# Define starting model
starting_conductivity_model = background_conductivity * np.ones(nC)

###############################################################
# Define the Physics of the DC Simulation
# ---------------------------------------
#
# Here, we define the physics of the DC resistivity simulation.
#
#

dc_simulation = dc.simulation.Simulation3DNodal(mesh,
                                                survey=dc_survey,
                                                sigmaMap=conductivity_map,
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