예제 #1
0
    def getCoreModel(self, Type):

        if Type == "Layer":
            active = self.mesh2D.vectorCCy < self.z0
            ind1 = (self.mesh2D.vectorCCy < self.z0) & (self.mesh2D.vectorCCy
                                                        >= self.z1)
            ind2 = (self.mesh2D.vectorCCy < self.z1) & (self.mesh2D.vectorCCy
                                                        >= self.z2)
            mapping2D = maps.SurjectVertical1D(
                self.mesh2D) * maps.InjectActiveCells(
                    self.mesh2D, active, self.sig0, nC=self.mesh2D.nCy)
            model2D = np.ones(self.mesh2D.nCy) * self.sig3
            model2D[ind1] = self.sig1
            model2D[ind2] = self.sig2
            model2D = model2D[active]
        elif Type == "Sphere":
            active = self.mesh2D.gridCC[:, 1] < self.z0
            ind1 = (self.mesh2D.gridCC[:, 1] <
                    self.z1) & (self.mesh2D.gridCC[:, 1] >= self.z1 - self.h)
            ind2 = (np.sqrt((self.mesh2D.gridCC[:, 0])**2 +
                            (self.mesh2D.gridCC[:, 1] - self.z2)**2) <= self.R)

            mapping2D = maps.InjectActiveCells(self.mesh2D,
                                               active,
                                               self.sig0,
                                               nC=self.mesh2D.nC)
            model2D = np.ones(self.mesh2D.nC) * self.sigb
            model2D[ind1] = self.sig1
            model2D[ind2] = self.sig2
            model2D = model2D[active]

        return model2D, mapping2D
예제 #2
0
파일: run.py 프로젝트: winnerer123/simpeg
def spectral_ip_mappings(
    mesh,
    indActive=None,
    inactive_eta=1e-4,
    inactive_tau=1e-4,
    inactive_c=1e-4,
    is_log_eta=True,
    is_log_tau=True,
    is_log_c=True,
):
    """
    Generates Mappings for Spectral Induced Polarization Simulation.
    Three parameters are required to be input:
    Chargeability (eta), Time constant (tau), and Frequency dependency (c).
    If there is no topography (indActive is None),
    model (m) can be either set to

    m = np.r_[log(eta), log(tau), log(c)] or m = np.r_[eta, tau, c]

    When indActive is not None, m is

    m = np.r_[log(eta[indAcitve]), log(tau[indAcitve]), log(c[indAcitve])] or
    m = np.r_[eta[indAcitve], tau[indAcitve], c[indAcitve]] or

    TODO: Illustrate input and output variables
    """

    if indActive is None:
        indActive = np.ones(mesh.nC, dtype=bool)

    actmap_eta = maps.InjectActiveCells(
        mesh, indActive=indActive, valInactive=inactive_eta
    )
    actmap_tau = maps.InjectActiveCells(
        mesh, indActive=indActive, valInactive=inactive_tau
    )
    actmap_c = maps.InjectActiveCells(mesh, indActive=indActive, valInactive=inactive_c)

    wires = maps.Wires(
        ("eta", indActive.sum()), ("tau", indActive.sum()), ("c", indActive.sum())
    )

    if is_log_eta:
        eta_map = actmap_eta * maps.ExpMap(nP=actmap_eta.nP) * wires.eta
    else:
        eta_map = actmap_eta * wires.eta

    if is_log_tau:
        tau_map = actmap_tau * maps.ExpMap(nP=actmap_tau.nP) * wires.tau
    else:
        tau_map = actmap_tau * wires.tau

    if is_log_c:
        c_map = actmap_c * maps.ExpMap(nP=actmap_c.nP) * wires.c
    else:
        c_map = actmap_c * wires.c

    return eta_map, tau_map, c_map, wires
예제 #3
0
    def test_nC_residual(self):

        # x-direction
        cs, ncx, ncz, npad = 1.0, 10.0, 10.0, 20
        hx = [(cs, ncx), (cs, npad, 1.3)]

        # z direction
        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

        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

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

        self.assertTrue(reg._nC_residual == regMesh.nC)
        self.assertTrue(
            all([fct._nC_residual == regMesh.nC for fct in reg.objfcts]))
예제 #4
0
    def setThreeLayerParam(self,
                           h1=12,
                           h2=12,
                           sig0=1e-8,
                           sig1=1e-1,
                           sig2=1e-2,
                           sig3=1e-2,
                           chi=0.0):
        self.h1 = h1  # 1st layer thickness
        self.h2 = h2  # 2nd layer thickness
        self.z0 = 0.0
        self.z1 = self.z0 - h1
        self.z2 = self.z0 - h1 - h2
        self.sig0 = sig0  # 0th layer \sigma (assumed to be air)
        self.sig1 = sig1  # 1st layer \sigma
        self.sig2 = sig2  # 2nd layer \sigma
        self.sig3 = sig3  # 3rd layer \sigma

        active = self.mesh.vectorCCz < self.z0
        ind1 = (self.mesh.vectorCCz < self.z0) & (self.mesh.vectorCCz >=
                                                  self.z1)
        ind2 = (self.mesh.vectorCCz < self.z1) & (self.mesh.vectorCCz >=
                                                  self.z2)
        self.mapping = maps.SurjectVertical1D(
            self.mesh) * maps.InjectActiveCells(
                self.mesh, active, sig0, nC=self.mesh.nCz)
        model = np.ones(self.mesh.nCz) * sig3
        model[ind1] = sig1
        model[ind2] = sig2
        self.m = model[active]
        self.mu = np.ones(self.mesh.nC) * mu_0
        self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0
        return self.m
예제 #5
0
    def setLayerSphereParam(
        self, d1=6, h=6, d2=16, R=4, sig0=1e-8, sigb=1e-2, sig1=1e-1, sig2=1.0, chi=0.0
    ):
        self.z0 = 0.0  # Surface elevation
        self.z1 = self.z0 - d1  # Depth to layer
        self.h = h  # Thickness of layer
        self.z2 = self.z0 - d2  # Depth to center of sphere
        self.R = R  # Radius of sphere
        self.sig0 = sig0  # Air conductivity
        self.sigb = sigb  # Background conductivity
        self.sig1 = sig1  # Layer conductivity
        self.sig2 = sig2  # Sphere conductivity

        active = self.mesh.gridCC[:, 2] < self.z0
        ind1 = (self.mesh.gridCC[:, 2] < self.z1) & (
            self.mesh.gridCC[:, 2] >= self.z1 - self.h
        )
        ind2 = (
            np.sqrt(
                (self.mesh.gridCC[:, 0]) ** 2 + (self.mesh.gridCC[:, 2] - self.z2) ** 2
            )
            <= self.R
        )

        self.mapping = maps.InjectActiveCells(self.mesh, active, sig0, nC=self.mesh.nC)
        model = np.ones(self.mesh.nC) * sigb
        model[ind1] = sig1
        model[ind2] = sig2
        self.m = model[active]
        self.mu = np.ones(self.mesh.nC) * mu_0
        self.mu[self.mesh.gridCC[:, 2] < 0.0] = (1.0 + chi) * mu_0
        return self.m
예제 #6
0
    def test_tripleMultiply(self):
        M = discretize.TensorMesh([2, 4], "0C")
        expMap = maps.ExpMap(M)
        vertMap = maps.SurjectVertical1D(M)
        actMap = maps.InjectActiveCells(M, M.vectorCCy <= 0, 10, nC=M.nCy)
        m = np.r_[1.0, 2.0]
        t_true = np.exp(np.r_[1, 1, 2, 2, 10, 10, 10, 10.0])

        self.assertLess(
            np.linalg.norm((expMap * vertMap * actMap * m) - t_true, np.inf),
            TOL)
        self.assertLess(
            np.linalg.norm(((expMap * vertMap * actMap) * m) - t_true, np.inf),
            TOL)
        self.assertLess(
            np.linalg.norm((expMap * vertMap * (actMap * m)) - t_true, np.inf),
            TOL)
        self.assertLess(
            np.linalg.norm((expMap * (vertMap * actMap) * m) - t_true, np.inf),
            TOL)
        self.assertLess(
            np.linalg.norm(((expMap * vertMap) * actMap * m) - t_true, np.inf),
            TOL)

        self.assertRaises(ValueError, lambda: expMap * actMap * vertMap)
        self.assertRaises(ValueError, lambda: actMap * vertMap * expMap)
예제 #7
0
def setUp_TDEM(prbtype="MagneticFluxDensity", rxcomp="bz", waveform="stepoff"):
    cs = 5.0
    ncx = 8
    ncy = 8
    ncz = 8
    npad = 4
    # 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

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

    rxtimes = np.logspace(-4, -3, 20)

    if waveform.upper() == "RAW":
        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)
        prb.timeSteps = [(1e-3, 5), (1e-4, 5), (5e-5, 10), (5e-5, 10),
                         (1e-4, 10)]
        rxtimes = t0 + rxtimes

    else:
        waveform = tdem.Src.StepOffWaveform()
        prb.timeSteps = [(1e-05, 10), (5e-05, 10), (2.5e-4, 10)]

    rxOffset = 10.0
    rx = getattr(tdem.Rx, "Point{}".format(rxcomp[:-1]))(np.r_[rxOffset, 0.0,
                                                               -1e-2], rxtimes,
                                                         rxcomp[-1])
    src = tdem.Src.MagDipole([rx],
                             loc=np.array([0.0, 0.0, 0.0]),
                             waveform=waveform)

    survey = tdem.Survey([src])

    prb.Solver = Solver

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

    prb.pair(survey)
    mesh = mesh

    return prb, m, mesh
예제 #8
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
예제 #9
0
    def test_activeCells(self):
        M = discretize.TensorMesh([2, 4], "0C")
        for actMap in [
            maps.InjectActiveCells(M, M.vectorCCy <= 0, 10, nC=M.nCy),
        ]:

            vertMap = maps.SurjectVertical1D(M)
            combo = vertMap * actMap
            m = np.r_[1.0, 2.0]
            mod = models.Model(m, combo)

            self.assertLess(
                np.linalg.norm(mod.transform - np.r_[1, 1, 2, 2, 10, 10, 10, 10.0]), TOL
            )
            self.assertLess((mod.transformDeriv - combo.deriv(m)).toarray().sum(), TOL)
예제 #10
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 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}$"])
예제 #12
0
tdem_survey = tdem.Survey(tdem_source_list)

# Define cylindrical mesh
hr = [(10.0, 50), (10.0, 10, 1.5)]
hz = [(10.0, 10, -1.5), (10.0, 100), (10.0, 10, 1.5)]
mesh = CylMesh([hr, 1, hz], x0="00C")

# Define model
air_conductivity = 1e-8
background_conductivity = 1e-1
layer_conductivity = 1e-2
pipe_conductivity = 1e1

ind_active = mesh.gridCC[:, 2] < 0
model_map = maps.InjectActiveCells(mesh, ind_active, air_conductivity)

conductivity_model = background_conductivity * np.ones(ind_active.sum())
ind_layer = (mesh.gridCC[ind_active, 2] > -200.0) & (mesh.gridCC[ind_active, 2] < -0)
conductivity_model[ind_layer] = layer_conductivity
ind_pipe = (
    (mesh.gridCC[ind_active, 0] < 50.0)
    & (mesh.gridCC[ind_active, 2] > -10000.0)
    & (mesh.gridCC[ind_active, 2] < 0.0)
)
conductivity_model[ind_pipe] = pipe_conductivity

# Plot conductivity model
mpl.rcParams.update({"font.size": 12})
fig = plt.figure(figsize=(5.5, 6))
예제 #13
0
# Starting/Reference Model and Mapping on OcTree Mesh
# ---------------------------------------------------
#
# Here, we create starting and/or reference models for the DC 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 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.
#
#
예제 #14
0
########################################################
# Starting/Reference Model and Mapping on OcTree Mesh
# ---------------------------------------------------
#
# Here, we would create starting and/or reference models for the DC 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 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)

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

conductivity_map = active_map * maps.ExpMap()

# Define 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 problem.
#

# Define the problem. Define the cells below topography and the mapping
예제 #15
0
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()
예제 #16
0
                             ntx)

# Refine at certain locations
M.refine_at_locations(mesh, source_locations)
M.refine_at_locations(mesh, receiver_locations)
mesh.finalize()

# Resistivity in Ohm m
res_background = 1.0
res_block = 100.0

# Find cells that are active in the forward modeling (cells below surface)
ind_active = surface2ind_topo(mesh, surface)

# Define mapping from model to active cells
model_map = maps.InjectActiveCells(mesh, ind_active, res_background)

# Define model. Models in SimPEG are vector arrays
model = res_background * np.ones(ind_active.sum())
ind_block = utils.get_ind_block(mesh, ind_active, box_coordinates)
model[ind_block] = res_block

# Run the adaptive meshing algorithm
mesh, ex, ey, ez, diff_list = iterator(mesh,
                                       domain,
                                       surface,
                                       cell_width,
                                       box_surface,
                                       box_coordinates,
                                       receiver_locations,
                                       source_locations,
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)
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
예제 #19
0
# Mappings
# ---------
#
# 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)
예제 #20
0
# resistive block within a moderately conductive background. Note that
# you can carry through this work flow with a resistivity model if desired.
# 

# Define conductivity model in S/m (or resistivity model in Ohm m)
air_value = 1e-8
background_value = 1e-2
conductor_value = 1e-1
resistor_value = 1e-3

# Find active cells in forward modeling (cell below surface)
ind_active = surface2ind_topo(mesh, topo_xyz)

# Define mapping from model to active cells
nC = int(ind_active.sum())
conductivity_map = maps.InjectActiveCells(mesh, ind_active, air_value)

# Define model
conductivity_model = background_value * np.ones(nC)

ind_conductor = model_builder.getIndicesSphere(
    np.r_[-350., 0., -300.], 160., mesh.cell_centers[ind_active, :]
)
conductivity_model[ind_conductor] = conductor_value

ind_resistor = model_builder.getIndicesSphere(
    np.r_[350., 0., -300.], 160., mesh.cell_centers[ind_active, :]
)
conductivity_model[ind_resistor] = resistor_value

# Plot Conductivity Model
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)
예제 #22
0
mesh.finalize()

background_value = 100.0
dyke_value = 40.0
block_value = 70.0

# Define surface topography as an (N, 3) np.array. You could also load a file
# containing the xyz points
[xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy)
zz = -3 * np.exp((xx**2 + yy**2) / 60**2) + 45.0
topo = np.c_[mkvc(xx), mkvc(yy), mkvc(zz)]

# Find cells below topography and define mapping
air_value = 0.0
ind_active = surface2ind_topo(mesh, topo)
model_map = maps.InjectActiveCells(mesh, ind_active, air_value)

# 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

# We can plot a slice of the model at Y=-2.5
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()
예제 #24
0
    )

    local_misfits.append(
        data_misfit.L2DataMisfit(data=data_object, simulation=simulation))

# Our global misfit
global_misfit = local_misfits[0] + local_misfits[1]

# Plot the model on different meshes
fig = plt.figure(figsize=(12, 6))
for ii, local_misfit in enumerate(local_misfits):

    local_mesh = local_misfit.simulation.mesh
    local_map = local_misfit.simulation.rhoMap

    inject_local = maps.InjectActiveCells(local_mesh, local_map.local_active,
                                          np.nan)

    ax = plt.subplot(2, 2, ii + 1)
    local_mesh.plotSlice(inject_local * (local_map * model),
                         normal="Y",
                         ax=ax,
                         grid=True)
    ax.set_aspect("equal")
    ax.set_title(f"Mesh {ii+1}. Active cells {local_map.local_active.sum()}")

# Create active map to go from reduce set to full
inject_global = maps.InjectActiveCells(mesh, activeCells, np.nan)

ax = plt.subplot(2, 1, 2)
mesh.plotSlice(inject_global * model, normal="Y", ax=ax, grid=True)
ax.set_title(f"Global Mesh. Active cells {activeCells.sum()}")
예제 #25
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}$"])
예제 #26
0
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)
예제 #27
0
true_model[ind_block] = block_density

# You can also use SimPEG utilities to add structures to the model more concisely
ind_sphere = model_builder.getIndicesSphere(np.r_[35.0, 0.0, -40.0], 15.0,
                                            mesh.gridCC)
ind_sphere = ind_sphere[ind_active]
true_model[ind_sphere] = sphere_density

############################################################
# Plotting True Model and Recovered Model
# ---------------------------------------
#

# Plot True Model
fig = plt.figure(figsize=(9, 4))
plotting_map = maps.InjectActiveCells(mesh, ind_active, np.nan)

ax1 = fig.add_axes([0.1, 0.1, 0.73, 0.8])
mesh.plotSlice(
    plotting_map * true_model,
    normal="Y",
    ax=ax1,
    ind=int(mesh.nCy / 2),
    grid=True,
    clim=(np.min(true_model), np.max(true_model)),
    pcolorOpts={"cmap": "viridis"},
)
ax1.set_title("Model slice at y = 0 m")

ax2 = fig.add_axes([0.85, 0.1, 0.05, 0.8])
norm = mpl.colors.Normalize(vmin=np.min(true_model), vmax=np.max(true_model))
예제 #28
0
    def setUp(self):

        ndv = -100
        # Create a self.mesh
        dx = 5.0

        hxind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hyind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)]
        hzind = [(dx, 5, -1.3), (dx, 6)]

        self.mesh = discretize.TensorMesh([hxind, hyind, hzind], "CCC")

        # Get index of the center
        midx = int(self.mesh.nCx / 2)
        midy = int(self.mesh.nCy / 2)

        # Lets create a simple Gaussian topo and set the active cells
        [xx, yy] = np.meshgrid(self.mesh.vectorNx, self.mesh.vectorNy)
        zz = -np.exp((xx**2 + yy**2) / 75**2) + self.mesh.vectorNz[-1]

        # Go from topo to actv cells
        topo = np.c_[utils.mkvc(xx), utils.mkvc(yy), utils.mkvc(zz)]
        actv = utils.surface2ind_topo(self.mesh, topo, "N")
        actv = np.where(actv)[0]

        # Create active map to go from reduce space to full
        self.actvMap = maps.InjectActiveCells(self.mesh, actv, -100)
        nC = len(actv)

        # Create and array of observation points
        xr = np.linspace(-20.0, 20.0, 20)
        yr = np.linspace(-20.0, 20.0, 20)
        X, Y = np.meshgrid(xr, yr)

        # Move the observation points 5m above the topo
        Z = -np.exp((X**2 + Y**2) / 75**2) + self.mesh.vectorNz[-1] + 5.0

        # Create a MAGsurvey
        locXYZ = np.c_[utils.mkvc(X.T), utils.mkvc(Y.T), utils.mkvc(Z.T)]
        rxLoc = gravity.Point(locXYZ)
        srcField = gravity.SourceField([rxLoc])
        survey = gravity.Survey(srcField)

        # We can now create a density model and generate data
        # Here a simple block in half-space
        model = np.zeros((self.mesh.nCx, self.mesh.nCy, self.mesh.nCz))
        model[(midx - 2):(midx + 2), (midy - 2):(midy + 2), -6:-2] = 0.5
        model = utils.mkvc(model)
        self.model = model[actv]

        # Create active map to go from reduce set to full
        actvMap = maps.InjectActiveCells(self.mesh, actv, ndv)

        # Create reduced identity map
        idenMap = maps.IdentityMap(nP=nC)

        # Create the forward model operator
        sim = gravity.Simulation3DIntegral(
            self.mesh,
            survey=survey,
            rhoMap=idenMap,
            actInd=actv,
            store_sensitivities="ram",
        )

        # Compute linear forward operator and compute some data
        # computing sensitivities to ram is best using dask processes
        with dask.config.set(scheduler="processes"):
            data = sim.make_synthetic_data(self.model,
                                           relative_error=0.0,
                                           noise_floor=0.001,
                                           add_noise=True)
        print(sim.G)

        # Create a regularization
        reg = regularization.Sparse(self.mesh, indActive=actv, mapping=idenMap)
        reg.norms = np.c_[0, 0, 0, 0]
        reg.gradientType = "component"
        # reg.eps_p, reg.eps_q = 5e-2, 1e-2

        # Data misfit function
        dmis = data_misfit.L2DataMisfit(simulation=sim, data=data)

        # Add directives to the inversion
        opt = optimization.ProjectedGNCG(maxIter=100,
                                         lower=-1.0,
                                         upper=1.0,
                                         maxIterLS=20,
                                         maxIterCG=10,
                                         tolCG=1e-3)
        invProb = inverse_problem.BaseInvProblem(dmis, reg, opt, beta=1e8)

        # Here is where the norms are applied
        IRLS = directives.Update_IRLS(f_min_change=1e-4, minGNiter=1)
        update_Jacobi = directives.UpdatePreconditioner()
        sensitivity_weights = directives.UpdateSensitivityWeights(
            everyIter=False)
        self.inv = inversion.BaseInversion(
            invProb, directiveList=[IRLS, sensitivity_weights, update_Jacobi])
        self.sim = sim
예제 #29
0
        },
        method="nearest",
    )
plt.subplots_adjust(hspace=-0.25, wspace=0.1)
plt.show()

# Load Topo
topo_file = io_utils.download(
    "https://storage.googleapis.com/simpeg/pgi_tutorial_assets/CDED_Lake_warp.xyz"
)
topo = np.genfromtxt(topo_file, skip_header=1)
# find the active cells
actv = utils.surface2ind_topo(mesh, topo, gridLoc="CC")
# Create active map to go from reduce set to full
ndv = np.nan
actvMap = maps.InjectActiveCells(mesh, actv, ndv)
nactv = int(actv.sum())

# Create simulations and data misfits
# Wires mapping
wires = maps.Wires(("den", actvMap.nP), ("sus", actvMap.nP))
gravmap = actvMap * wires.den
magmap = actvMap * wires.sus
idenMap = maps.IdentityMap(nP=nactv)
# Grav problem
simulation_grav = pf.gravity.simulation.Simulation3DIntegral(
    survey=data_grav.survey,
    mesh=mesh,
    rhoMap=wires.den,
    actInd=actv,
)
예제 #30
0
    def setUp(self):

        cs = 25.0
        hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hz = [(cs, 0, -1.3), (cs, 20), (cs, 0, 1.3)]
        mesh = discretize.TensorMesh([hx, hy, hz], x0="CCC")
        blkind0 = utils.model_builder.getIndicesSphere(
            np.r_[-100.0, -100.0, -200.0], 75.0, mesh.gridCC)
        blkind1 = utils.model_builder.getIndicesSphere(
            np.r_[100.0, 100.0, -200.0], 75.0, mesh.gridCC)
        sigma = np.ones(mesh.nC) * 1e-2
        airind = mesh.gridCC[:, 2] > 0.0
        sigma[airind] = 1e-8
        eta = np.zeros(mesh.nC)
        tau = np.ones_like(sigma) * 1.0
        c = np.ones_like(sigma) * 0.5

        eta[blkind0] = 0.1
        eta[blkind1] = 0.1
        tau[blkind0] = 0.1
        tau[blkind1] = 0.01

        actmapeta = maps.InjectActiveCells(mesh, ~airind, 0.0)
        actmaptau = maps.InjectActiveCells(mesh, ~airind, 1.0)
        actmapc = maps.InjectActiveCells(mesh, ~airind, 1.0)

        x = mesh.vectorCCx[(mesh.vectorCCx > -155.0)
                           & (mesh.vectorCCx < 155.0)]
        y = mesh.vectorCCy[(mesh.vectorCCy > -155.0)
                           & (mesh.vectorCCy < 155.0)]
        Aloc = np.r_[-200.0, 0.0, 0.0]
        Bloc = np.r_[200.0, 0.0, 0.0]
        M = utils.ndgrid(x - 25.0, y, np.r_[0.0])
        N = utils.ndgrid(x + 25.0, y, np.r_[0.0])

        times = np.arange(10) * 1e-3 + 1e-3
        rx = sip.receivers.Dipole(M, N, times)
        src = sip.sources.Dipole([rx], Aloc, Bloc)
        survey = sip.Survey([src])

        wires = maps.Wires(("eta", actmapeta.nP), ("taui", actmaptau.nP),
                           ("c", actmapc.nP))
        problem = sip.Simulation3DNodal(
            mesh,
            survey=survey,
            sigma=sigma,
            etaMap=actmapeta * wires.eta,
            tauiMap=actmaptau * wires.taui,
            cMap=actmapc * wires.c,
            actinds=~airind,
            storeJ=False,
            verbose=False,
        )

        problem.solver = Solver
        mSynth = np.r_[eta[~airind], 1.0 / tau[~airind], c[~airind]]
        dobs = problem.make_synthetic_data(mSynth, add_noise=True)
        # Now set up the problem to do some minimization
        dmis = data_misfit.L2DataMisfit(data=dobs, simulation=problem)
        reg_eta = regularization.Sparse(mesh,
                                        mapping=wires.eta,
                                        indActive=~airind)
        reg_taui = regularization.Sparse(mesh,
                                         mapping=wires.taui,
                                         indActive=~airind)
        reg_c = regularization.Sparse(mesh, mapping=wires.c, indActive=~airind)
        reg = reg_eta + reg_taui + reg_c
        opt = optimization.InexactGaussNewton(maxIterLS=20,
                                              maxIter=10,
                                              tolF=1e-6,
                                              tolX=1e-6,
                                              tolG=1e-6,
                                              maxIterCG=6)
        invProb = inverse_problem.BaseInvProblem(dmis, reg, opt, beta=1e4)
        inv = inversion.BaseInversion(invProb)

        self.inv = inv
        self.reg = reg
        self.p = problem
        self.mesh = mesh
        self.m0 = mSynth
        self.survey = survey
        self.dmis = dmis
        self.dobs = dobs