Example #1
0
    def test_basic_inversion(self):
        """
        Test to see if inversion recovers model
        """

        h = [(2, 30)]
        meshObj = Mesh.TensorMesh((h, h, [(2, 10)]), x0='CCN')

        mod = 0.00025 * np.ones(meshObj.nC)
        mod[(meshObj.gridCC[:, 0] > -4.) & (meshObj.gridCC[:, 1] > -4.) &
            (meshObj.gridCC[:, 0] < 4.) & (meshObj.gridCC[:, 1] < 4.)] = 0.001

        times = np.logspace(-4, -2, 5)
        waveObj = VRM.WaveformVRM.SquarePulse(0.02)

        x, y = np.meshgrid(np.linspace(-17, 17, 16), np.linspace(-17, 17, 16))
        x, y, z = mkvc(x), mkvc(y), 0.5 * np.ones(np.size(x))
        rxList = [VRM.Rx.Point(np.c_[x, y, z], times, 'dbdt', 'z')]

        txNodes = np.array([[-20, -20, 0.001], [20, -20,
                                                0.001], [20, 20, 0.001],
                            [-20, 20, 0.01], [-20, -20, 0.001]])
        txList = [VRM.Src.LineCurrent(rxList, txNodes, 1., waveObj)]

        Survey = VRM.Survey(txList)
        Problem = VRM.Problem_Linear(meshObj, refFact=2)
        Problem.pair(Survey)
        Survey.makeSyntheticData(mod)
        Survey.eps = 1e-11

        dmis = DataMisfit.l2_DataMisfit(Survey)
        W = mkvc((np.sum(np.array(Problem.A)**2, axis=0)))**0.25
        reg = Regularization.Simple(meshObj,
                                    alpha_s=0.01,
                                    alpha_x=1.,
                                    alpha_y=1.,
                                    alpha_z=1.,
                                    cell_weights=W)
        opt = Optimization.ProjectedGNCG(maxIter=20,
                                         lower=0.,
                                         upper=1e-2,
                                         maxIterLS=20,
                                         tolCG=1e-4)
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
        directives = [
            Directives.BetaSchedule(coolingFactor=2, coolingRate=1),
            Directives.TargetMisfit()
        ]
        inv = Inversion.BaseInversion(invProb, directiveList=directives)

        m0 = 1e-6 * np.ones(len(mod))
        mrec = inv.run(m0)

        dmis_final = np.sum(
            (dmis.W.diagonal() * (Survey.dobs - Problem.fields(mrec)))**2)
        mod_err_2 = np.sqrt(np.sum((mrec - mod)**2)) / np.size(mod)
        mod_err_inf = np.max(np.abs(mrec - mod))

        self.assertTrue(dmis_final < Survey.nD and mod_err_2 < 5e-6
                        and mod_err_inf < np.max(mod))
    def solve(self):
        # Tikhonov Inversion
        ####################

        # Initial model values
        m0 = np.median(self.ln_sigback) * np.ones(self.mapping.nP)
        m0 += np.random.randn(m0.size)

        # Misfit functional
        dmis = DataMisfit.l2_DataMisfit(self.survey.simpeg_survey)
        # Regularization functional
        regT = Regularization.Simple(self.mesh,
                                     alpha_s=10.0,
                                     alpha_x=10.0,
                                     alpha_y=10.0,
                                     alpha_z=10.0,
                                     indActive=self.actind)

        # Personal preference for this solver with a Jacobi preconditioner
        opt = Optimization.ProjectedGNCG(maxIter=8, tolX=1, maxIterCG=30)
        #opt = Optimization.ProjectedGradient(maxIter=100, tolX=1e-2,
        #                                 maxIterLS=20, maxIterCG=30, tolCG=1e-4)

        opt.printers.append(Optimization.IterationPrinters.iterationLS)
        #print(opt.printersLS)

        # Optimization class keeps value of 'xc'. Seems to be solution for the model parameters
        opt.remember('xc')
        invProb = InvProblem.BaseInvProblem(dmis, regT, opt)

        # Options for the inversion algorithm in particular selection of Beta weight for regularization.

        # How to choose initial estimate for beta
        beta = Directives.BetaEstimate_ByEig(beta0_ratio=1.)
        Target = Directives.TargetMisfit()
        # Beta changing algorithm.
        betaSched = Directives.BetaSchedule(coolingFactor=5., coolingRate=2)
        # Change model weights, seems sensitivity of conductivity ?? Not sure.
        updateSensW = Directives.UpdateSensitivityWeights(threshold=1e-3)
        # Use Jacobi preconditioner ( the only available).
        update_Jacobi = Directives.UpdatePreconditioner()

        inv = Inversion.BaseInversion(invProb,
                                      directiveList=[
                                          beta, Target, betaSched, updateSensW,
                                          update_Jacobi
                                      ])

        self.minv = inv.run(m0)
Example #3
0
 def solve(self):
     # initial values/model
     m0 = numpy.median(-4) * numpy.ones(self.mapping.nP)
     # Data Misfit
     dataMisfit = DataMisfit.l2_DataMisfit(self.survey)
     # Regularization
     regT = Regularization.Simple(self.mesh, indActive=self.activeCellIndices, alpha_s=1e-6, alpha_x=1., alpha_y=1., alpha_z=1.)
     # Optimization Scheme
     opt = Optimization.InexactGaussNewton(maxIter=10)
     # Form the problem
     opt.remember('xc')
     invProb = InvProblem.BaseInvProblem(dataMisfit, regT, opt)
     # Directives for Inversions
     beta = Directives.BetaEstimate_ByEig(beta0_ratio=0.5e+1)
     Target = Directives.TargetMisfit()
     betaSched = Directives.BetaSchedule(coolingFactor=5., coolingRate=2)
     inversion = Inversion.BaseInversion(invProb, directiveList=[beta, Target, betaSched])
     # Run Inversion
     self.invModelOnActiveCells = inversion.run(m0)
     self.invModelOnAllCells = self.givenModelCond * numpy.ones_like(self.givenModelCond)
     self.invModelOnAllCells[self.activeCellIndices] = self.invModelOnActiveCells
     self.invModelOnCoreCells = self.invModelOnAllCells[self.coreMeshCellIndices]
     pass
def run(plotIt=True, survey_type="dipole-dipole", p=0., qx=2., qz=2.):
    np.random.seed(1)
    # Initiate I/O class for DC
    IO = DC.IO()
    # Obtain ABMN locations

    xmin, xmax = 0., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl,
                                     survey_type=survey_type,
                                     dim=2,
                                     a=10,
                                     b=10,
                                     n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(survey.a_locations,
                                              survey.b_locations,
                                              survey.m_locations,
                                              survey.n_locations,
                                              survey_type,
                                              data_dc_type='volt')

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

    # Build a conductivity model
    blk_inds_c = Utils.ModelBuilder.getIndicesSphere(np.r_[60., -25.], 12.5,
                                                     mesh.gridCC)
    blk_inds_r = Utils.ModelBuilder.getIndicesSphere(np.r_[140., -25.], 12.5,
                                                     mesh.gridCC)
    layer_inds = mesh.gridCC[:, 1] > -5.
    sigma = np.ones(mesh.nC) * 1. / 100.
    sigma[blk_inds_c] = 1. / 10.
    sigma[blk_inds_r] = 1. / 1000.
    sigma[~actind] = 1. / 1e8
    rho = 1. / 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.Problem2D_N(mesh,
                         rhoMap=mapping,
                         storeJ=True,
                         Solver=Solver,
                         verbose=True)
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

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

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(survey.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.)

    # Set uncertainty
    # floor
    eps = 10**(-3.2)
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1. / 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.]
    IRLS = Directives.Update_IRLS(maxIRLSiter=20,
                                  minGNiter=1,
                                  betaSearch=False,
                                  fix_Jmatrix=True)

    opt = Optimization.InexactGaussNewton(maxIter=40)
    invProb = InvProblem.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., 15, 25, 13  # padded cyl mesh
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        plt.tight_layout(pad=1.5)

        if saveFig is True:
            plt.savefig('example1.png', dpi=600)
Example #6
0
def run(plotIt=False):

    O = np.r_[-1.2, -1.]
    D = np.r_[10., 10.]
    x = np.r_[0., 1.]
    y = np.r_[0., 1.]
    print('length:', StraightRay.lengthInCell(O, D, x, y, plotIt=plotIt))
    O = np.r_[0, -1.]
    D = np.r_[1., 1.] * 1.5
    print('length:', StraightRay.lengthInCell(O,
                                              D,
                                              x * 2,
                                              y * 2,
                                              plotIt=plotIt))

    nC = 20
    M = Mesh.TensorMesh([nC, nC])
    y = np.linspace(0., 1., nC / 2)
    rlocs = np.c_[y * 0 + M.vectorCCx[-1], y]
    rx = StraightRay.Rx(rlocs, None)

    srcList = [
        StraightRay.Src(loc=np.r_[M.vectorCCx[0], yi], rxList=[rx]) for yi in y
    ]

    survey = StraightRay.Survey(srcList)
    problem = StraightRay.Problem(M, slownessMap=Maps.IdentityMap(M))
    problem.pair(survey)

    s = Utils.mkvc(Utils.ModelBuilder.randomModel(M.vnC)) + 1.
    survey.dobs = survey.dpred(s)
    survey.std = 0.01

    # Create an optimization program

    reg = Regularization.Tikhonov(M)
    dmis = DataMisfit.l2_DataMisfit(survey)
    opt = Optimization.InexactGaussNewton(maxIter=40)
    opt.remember('xc')
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    beta = Directives.BetaSchedule()
    betaest = Directives.BetaEstimate_ByEig()
    inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest])

    # Start the inversion with a model of zeros, and run the inversion
    m0 = np.ones(M.nC) * 1.5
    mopt = inv.run(m0)

    if plotIt is True:
        fig, ax = plt.subplots(1, 2, figsize=(8, 4))
        ax[1].plot(survey.dobs)
        ax[1].plot(survey.dpred(m0), 's')
        ax[1].plot(survey.dpred(mopt), 'o')
        ax[1].legend(['dobs', 'starting dpred', 'dpred'])
        M.plotImage(s, ax=ax[0])
        survey.plot(ax=ax[0])
        ax[0].set_title('survey')

        plt.tight_layout()

    if plotIt is True:
        fig, ax = plt.subplots(1, 3, figsize=(12, 4))
        plt.colorbar(M.plotImage(m0, ax=ax[0])[0], ax=ax[0])
        plt.colorbar(M.plotImage(mopt, ax=ax[1])[0], ax=ax[1])
        plt.colorbar(M.plotImage(s, ax=ax[2])[0], ax=ax[2])

        ax[0].set_title('Starting Model')
        ax[1].set_title('Recovered Model')
        ax[2].set_title('True Model')

        plt.tight_layout()
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., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl,
                                     survey_type=survey_type,
                                     dim=2,
                                     a=10,
                                     b=10,
                                     n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(survey.a_locations,
                                              survey.b_locations,
                                              survey.m_locations,
                                              survey.n_locations,
                                              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.])
    survey.drapeTopo(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.Problem2D_N(mesh, rhoMap=mapping, storeJ=True, Solver=Solver)
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    # Make synthetic DC data with 5% Gaussian noise
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

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

    # Show apparent resisitivty histogram
    fig = plt.figure()
    out = hist(survey.dobs / IO.G, bins=20)
    plt.show()
    # Set uncertainty
    # floor
    eps = 10**(-3.2)
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1. / uncert

    # Map for a regularization
    mesh_1d = Mesh.TensorMesh([parametric_block.nP])
    # Related to inversion
    reg = Regularization.Simple(mesh_1d, alpha_x=0.)
    opt = Optimization.InexactGaussNewton(maxIter=10)
    invProb = InvProblem.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.
    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):

    M = Mesh.TensorMesh([np.ones(40)], x0='N')
    M.setCellGradBC('dirichlet')
    # We will use the haverkamp empirical model with parameters from Celia1990
    k_fun, theta_fun = Richards.Empirical.haverkamp(M,
                                                    A=1.1750e+06,
                                                    gamma=4.74,
                                                    alpha=1.6110e+06,
                                                    theta_s=0.287,
                                                    theta_r=0.075,
                                                    beta=3.96)

    # Here we are making saturated hydraulic conductivity
    # an exponential mapping to the model (defined below)
    k_fun.KsMap = Maps.ExpMap(nP=M.nC)

    # Setup the boundary and initial conditions
    bc = np.array([-61.5, -20.7])
    h = np.zeros(M.nC) + bc[0]
    prob = Richards.RichardsProblem(M,
                                    hydraulic_conductivity=k_fun,
                                    water_retention=theta_fun,
                                    boundary_conditions=bc,
                                    initial_conditions=h,
                                    do_newton=False,
                                    method='mixed',
                                    debug=False)
    prob.timeSteps = [(5, 25, 1.1), (60, 40)]

    # Create the survey
    locs = -np.arange(2, 38, 4.)
    times = np.arange(30, prob.timeMesh.vectorCCx[-1], 60)
    rxSat = Richards.SaturationRx(locs, times)
    survey = Richards.RichardsSurvey([rxSat])
    survey.pair(prob)

    # Create a simple model for Ks
    Ks = 1e-3
    mtrue = np.ones(M.nC) * np.log(Ks)
    mtrue[15:20] = np.log(5e-2)
    mtrue[20:35] = np.log(3e-3)
    mtrue[35:40] = np.log(1e-2)
    m0 = np.ones(M.nC) * np.log(Ks)

    # Create some synthetic data and fields
    stdev = 0.02  # The standard deviation for the noise
    Hs = prob.fields(mtrue)
    survey.makeSyntheticData(mtrue, std=stdev, f=Hs, force=True)

    # Setup a pretty standard inversion
    reg = Regularization.Tikhonov(M, alpha_s=1e-1)
    dmis = DataMisfit.l2_DataMisfit(survey)
    opt = Optimization.InexactGaussNewton(maxIter=20, maxIterCG=10)
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=4)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e2)
    target = Directives.TargetMisfit()
    dir_list = [beta, betaest, target]
    inv = Inversion.BaseInversion(invProb, directiveList=dir_list)

    mopt = inv.run(m0)

    Hs_opt = prob.fields(mopt)

    if plotIt:
        plt.figure(figsize=(14, 9))

        ax = plt.subplot(121)
        plt.semilogx(np.exp(np.c_[mopt, mtrue]), M.gridCC)
        plt.xlabel('Saturated Hydraulic Conductivity, $K_s$')
        plt.ylabel('Depth, cm')
        plt.semilogx([10**-3.9] * len(locs), locs, 'ro')
        plt.legend(('$m_{rec}$', '$m_{true}$', 'Data locations'), loc=4)

        ax = plt.subplot(222)
        mesh2d = Mesh.TensorMesh([prob.timeMesh.hx / 60, prob.mesh.hx], '0N')
        sats = [theta_fun(_) for _ in Hs]
        clr = mesh2d.plotImage(np.c_[sats][1:, :], ax=ax)
        cmap0 = matplotlib.cm.RdYlBu_r
        clr[0].set_cmap(cmap0)
        c = plt.colorbar(clr[0])
        c.set_label('Saturation $\\theta$')
        plt.xlabel('Time, minutes')
        plt.ylabel('Depth, cm')
        plt.title('True saturation over time')

        ax = plt.subplot(224)
        mesh2d = Mesh.TensorMesh([prob.timeMesh.hx / 60, prob.mesh.hx], '0N')
        sats = [theta_fun(_) for _ in Hs_opt]
        clr = mesh2d.plotImage(np.c_[sats][1:, :], ax=ax)
        cmap0 = matplotlib.cm.RdYlBu_r
        clr[0].set_cmap(cmap0)
        c = plt.colorbar(clr[0])
        c.set_label('Saturation $\\theta$')
        plt.xlabel('Time, minutes')
        plt.ylabel('Depth, cm')
        plt.title('Recovered saturation over time')

        plt.tight_layout()
Example #9
0
print '# of data: ', survey.dobs.shape

#Simple Inversion
regmesh = mesh
m0 = (-5.) * np.ones(mapping.nP)
dmis = DataMisfit.l2_DataMisfit(survey)
reg = Regularization.Tikhonov(regmesh)  #,mapping = mapping)#,indActive=actind)
reg.mref = m0
opt = Optimization.InexactGaussNewton(maxIter=20, tolX=1e-6)
opt.remember('xc')
invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
beta = Directives.BetaEstimate_ByEig(beta0=10., beta0_ratio=1e0)
reg.alpha_s = 1e-2
#beta = 0.
#invProb.beta = beta
betaSched = Directives.BetaSchedule(coolingFactor=5, coolingRate=2)
#sav0 = Directives.SaveEveryIteration()
#sav1 = Directives.SaveModelEveryIteration()
sav2 = Directives.SaveOutputDictEveryIteration()
inv = Inversion.BaseInversion(invProb, directiveList=[sav2, beta,
                                                      betaSched])  #sav0,sav1,

mtest = np.load('../Update_W_each_3it_5s_rademacher/finalresult.npy')
print "check misfit with W: ", dmis.eval(mtest) / survey.nD
mm = meshCore.plotImage(mtest[actind])
plt.colorbar(mm[0])
plt.show()

msimple = inv.run(m0)
mm = mesh.plotImage(msimple)
plt.colorbar(mm[0])
Example #10
0
    def run_inversion(
        self,
        maxIter=60,
        m0=0.0,
        mref=0.0,
        percentage=5,
        floor=0.1,
        chifact=1,
        beta0_ratio=1.0,
        coolingFactor=1,
        n_iter_per_beta=1,
        alpha_s=1.0,
        alpha_x=1.0,
        alpha_z=1.0,
        use_target=False,
        use_tikhonov=True,
        use_irls=False,
        p_s=2,
        p_x=2,
        p_y=2,
        p_z=2,
        beta_start=None,
    ):

        self.uncertainty = percentage * abs(self.survey.dobs) * 0.01 + floor

        m0 = np.ones(self.mesh.nC) * m0
        mref = np.ones(self.mesh.nC) * mref

        if ~use_tikhonov:
            reg = Regularization.Sparse(
                self.mesh,
                alpha_s=alpha_s,
                alpha_x=alpha_x,
                alpha_y=alpha_z,
                mref=mref,
                mapping=Maps.IdentityMap(self.mesh),
                cell_weights=self.mesh.vol,
            )
        else:
            reg = Regularization.Tikhonov(
                self.mesh,
                alpha_s=alpha_s,
                alpha_x=alpha_x,
                alpha_y=alpha_z,
                mref=mref,
                mapping=Maps.IdentityMap(self.mesh),
            )
        dmis = DataMisfit.l2_DataMisfit(self.survey)
        dmis.W = 1.0 / self.uncertainty

        opt = Optimization.ProjectedGNCG(maxIter=maxIter, maxIterCG=20)
        opt.lower = 0.0
        opt.remember("xc")
        opt.tolG = 1e-10
        opt.eps = 1e-10
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
        save = Directives.SaveOutputEveryIteration()
        beta_schedule = Directives.BetaSchedule(coolingFactor=coolingFactor,
                                                coolingRate=n_iter_per_beta)

        if use_irls:
            IRLS = Directives.Update_IRLS(
                f_min_change=1e-4,
                minGNiter=1,
                silent=False,
                maxIRLSiter=40,
                beta_tol=5e-1,
                coolEpsFact=1.3,
                chifact_start=chifact,
            )

            if beta_start is None:
                directives = [
                    Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio),
                    IRLS,
                    save,
                ]
            else:
                directives = [IRLS, save]
                invProb.beta = beta_start
            reg.norms = np.c_[p_s, p_x, p_z, 2]
        else:
            target = Directives.TargetMisfit(chifact=chifact)
            directives = [
                Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio),
                beta_schedule,
                save,
            ]
            if use_target:
                directives.append(target)

        inv = Inversion.BaseInversion(invProb, directiveList=directives)
        mopt = inv.run(m0)
        model = opt.recall("xc")
        model.append(mopt)
        pred = []
        for m in model:
            pred.append(self.survey.dpred(m))
        return model, pred, save
Example #11
0
def run(plotIt=True):
    """
        EM: TDEM: 1D: Inversion
        =======================

        Here we will create and run a TDEM 1D inversion.

    """

    cs, ncx, ncz, npad = 5., 25, 15, 15
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')

    active = mesh.vectorCCz < 0.
    layer = (mesh.vectorCCz < 0.) & (mesh.vectorCCz >= -100.)
    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 = EM.TDEM.Rx.Point_b(np.array([[rxOffset, 0., 30]]),
                            np.logspace(-5, -3, 31), 'z')
    src = EM.TDEM.Src.MagDipole([rx], loc=np.array([0., 0., 80]))
    survey = EM.TDEM.Survey([src])
    prb = EM.TDEM.Problem3D_b(mesh, sigmaMap=mapping)

    prb.Solver = SolverLU
    prb.timeSteps = [(1e-06, 20), (1e-05, 20), (0.0001, 20)]
    prb.pair(survey)

    # create observed data
    std = 0.05

    survey.dobs = survey.makeSyntheticData(mtrue, std)
    survey.std = std
    survey.eps = 1e-5 * np.linalg.norm(survey.dobs)

    dmisfit = DataMisfit.l2_DataMisfit(survey)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Tikhonov(regMesh, alpha_s=1e-2, alpha_x=1.)
    opt = Optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5)
    invProb = InvProblem.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)
    prb.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, survey.dtrue, 'b.-')
        ax[0].loglog(rx.times, survey.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}$'])
Example #12
0
def run_inversion(
    m0, survey, actind, mesh,
    std, eps,
    maxIter=15, beta0_ratio=1e0,
    coolingFactor=5, coolingRate=2,
    upper=np.inf, lower=-np.inf,
    use_sensitivity_weight=False,
    alpha_s=1e-4,
    alpha_x=1.,
    alpha_y=1.,
    alpha_z=1.,
):
    """
    Run IP inversion
    """
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1./uncert
    # Map for a regularization
    regmap = Maps.IdentityMap(nP=int(actind.sum()))
    # Related to inversion
    if use_sensitivity_weight:
        reg = Regularization.Sparse(
            mesh, indActive=actind, mapping=regmap
        )
        reg.alpha_s = alpha_s
        reg.alpha_x = alpha_x
        reg.alpha_y = alpha_y
        reg.alpha_z = alpha_z
    else:
        reg = Regularization.Sparse(
            mesh, indActive=actind, mapping=regmap,
            cell_weights=mesh.vol[actind]
        )
        reg.alpha_s = alpha_s
        reg.alpha_x = alpha_x
        reg.alpha_y = alpha_y
        reg.alpha_z = alpha_z
    opt = Optimization.ProjectedGNCG(maxIter=maxIter, upper=upper, lower=lower)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    beta = Directives.BetaSchedule(
        coolingFactor=coolingFactor, coolingRate=coolingRate
    )
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio)
    target = Directives.TargetMisfit()

    # Need to have basice saving function
    if use_sensitivity_weight:
        updateSensW = Directives.UpdateSensitivityWeights()
        update_Jacobi = Directives.UpdatePreconditioner()
        directiveList = [
            beta, betaest, target, update_Jacobi
        ]
    else:
        directiveList = [
            beta, betaest, target
        ]
    inv = Inversion.BaseInversion(
        invProb, directiveList=directiveList
        )
    opt.LSshorten = 0.5
    opt.remember('xc')

    # Run inversion
    mopt = inv.run(m0)
    return mopt, invProb.dpred
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., 200.
    ymin, ymax = 0., 0.
    zmin, zmax = 0, 0
    endl = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]])
    # Generate DC survey object
    survey = DC.Utils.gen_DCIPsurvey(endl, survey_type=survey_type, dim=2,
                                     a=10, b=10, n=10)
    survey.getABMN_locations()
    survey = IO.from_ambn_locations_to_survey(
        survey.a_locations, survey.b_locations,
        survey.m_locations, survey.n_locations,
        survey_type, data_dc_type='volt'
    )

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

    # Build a conductivity model
    blk_inds_c = Utils.ModelBuilder.getIndicesSphere(
        np.r_[60., -25.], 12.5, mesh.gridCC
    )
    blk_inds_r = Utils.ModelBuilder.getIndicesSphere(
        np.r_[140., -25.], 12.5, mesh.gridCC
    )
    layer_inds = mesh.gridCC[:, 1] > -5.
    sigma = np.ones(mesh.nC)*1./100.
    sigma[blk_inds_c] = 1./10.
    sigma[blk_inds_r] = 1./1000.
    sigma[~actind] = 1./1e8
    rho = 1./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.Problem2D_N(
        mesh, rhoMap=mapping, storeJ=True,
        Solver=Solver
    )
    # Pair problem with survey
    try:
        prb.pair(survey)
    except:
        survey.unpair()
        prb.pair(survey)

    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
    dtrue = survey.makeSyntheticData(mtrue, std=0.05, force=True)

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

    # Show apparent resisitivty histogram
    if plotIt:
        fig = plt.figure()
        out = hist(survey.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.)

    # Set uncertainty
    # floor (10 ohm-m)
    eps = 1.
    # percentage
    std = 0.05
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1./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 = InvProblem.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, betaest, target, updateSensW, 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()
Example #14
0
def run(plotIt=True):
    """
        EM: TDEM: 1D: Inversion with VTEM waveform
        ==========================================

        Here we will create and run a TDEM 1D inversion,
        with VTEM waveform of which initial condition
        is zero, but have some on- and off-time.
    """

    cs, ncx, ncz, npad = 5., 25, 24, 15
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')

    active = mesh.vectorCCz < 0.
    layer = (mesh.vectorCCz < -50.) & (mesh.vectorCCz >= -150.)
    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., np.zeros_like(x)]

    prb = EM.TDEM.Problem3D_b(mesh, sigmaMap=mapping)
    prb.Solver = Solver
    prb.timeSteps = [(1e-3, 5), (1e-4, 5), (5e-5, 10), (5e-5, 5), (1e-4, 10),
                     (5e-4, 10)]

    # Use VTEM waveform
    out = EM.Utils.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 = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun)

    rx = EM.TDEM.Rx.Point_dbdt(rxloc, np.logspace(-4, -2.5, 11) + t0, 'z')
    src = EM.TDEM.Src.CircularLoop([rx],
                                   waveform=waveform,
                                   loc=np.array([0., 0., 0.]),
                                   radius=10.)
    survey = EM.TDEM.Survey([src])
    prb.pair(survey)
    # create observed data
    std = 0.02

    survey.dobs = survey.makeSyntheticData(mtrue, std)
    # dobs = survey.dpred(mtrue)
    survey.std = std
    survey.eps = 1e-11

    dmisfit = DataMisfit.l2_DataMisfit(survey)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Simple(regMesh)
    opt = Optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    target = Directives.TargetMisfit()
    # Create an inversion object
    beta = Directives.BetaSchedule(coolingFactor=1., coolingRate=2.)
    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 = survey.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}$'])
Example #15
0
def run(plotIt=True):

    cs, ncx, ncz, npad = 5., 25, 15, 15
    hx = [(cs, ncx), (cs, npad, 1.3)]
    hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')

    layerz = -100.

    active = mesh.vectorCCz < 0.
    layer = (mesh.vectorCCz < 0.) & (mesh.vectorCCz >= layerz)
    actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz)
    mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap
    sig_half = 2e-2
    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])

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        ax.set_ylim(-500, 0)
        ax.set_xlim(1e-3, 1e-1)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    rxOffset = 10.
    bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., 1e-3]]),
                             orientation='z',
                             component='imag')

    freqs = np.logspace(1, 3, 10)
    srcLoc = np.array([0., 0., 10.])

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

    survey = EM.FDEM.Survey(srcList)
    prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver)
    prb.pair(survey)

    std = 0.05
    survey.makeSyntheticData(mtrue, std)

    survey.std = std
    survey.eps = np.linalg.norm(survey.dtrue) * 1e-5

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(6, 6))
        ax.semilogx(freqs, survey.dtrue[:freqs.size], 'b.-')
        ax.semilogx(freqs, survey.dobs[:freqs.size], 'r.-')
        ax.legend(('Noisefree', '$d^{obs}$'), fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.set_ylabel('$B_z$ (T)', fontsize=16)
        ax.set_xlabel('Time (s)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)

    dmisfit = DataMisfit.l2_DataMisfit(survey)
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Tikhonov(regMesh)
    opt = Optimization.InexactGaussNewton(maxIter=6)
    invProb = InvProblem.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)
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    mopt = inv.run(m0)

    if plotIt:
        fig, ax = plt.subplots(1, 1, figsize=(3, 6))
        plt.semilogx(sigma[active], mesh.vectorCCz[active])
        plt.semilogx(np.exp(mopt), mesh.vectorCCz[active])
        ax.set_ylim(-500, 0)
        ax.set_xlim(1e-3, 1e-1)
        ax.set_xlabel('Conductivity (S/m)', fontsize=14)
        ax.set_ylabel('Depth (m)', fontsize=14)
        ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)
        plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'], loc='best')
Example #16
0
def run(plotIt=True):
    """
    1D FDEM Mu Inversion
    ====================

    1D inversion of Magnetic Susceptibility from FDEM data assuming a fixed
    electrical conductivity

    """

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

    # Geologic Parameters model
    layerz = np.r_[-100., -50.]
    layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1])
    active = mesh.vectorCCz < 0.

    # Electrical Conductivity
    sig_half = 1e-2  # Half-space conductivity
    sig_air = 1e-8  # Air conductivity
    sig_layer = 1e-2  # Layer conductivity
    sigma = np.ones(mesh.nCz) * sig_air
    sigma[active] = sig_half
    sigma[layer] = sig_layer

    # mur - relative magnetic permeability
    mur_half = 1.
    mur_air = 1.
    mur_layer = 2.
    mur = np.ones(mesh.nCz) * mur_air
    mur[active] = mur_half
    mur[layer] = mur_layer

    mtrue = mur[active]

    # Maps
    actMap = Maps.InjectActiveCells(mesh, active, mur_air, nC=mesh.nCz)
    surj1Dmap = Maps.SurjectVertical1D(mesh)
    murMap = Maps.MuRelative(mesh)

    # Mapping
    muMap = murMap * surj1Dmap * actMap

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

    freqs = np.linspace(2000, 10000, 10)  #np.logspace(3, 4, 10)
    srcLoc = np.array([0., 0., 30.])

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

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

    surveyFD = FDEM.Survey(srcList)
    prbFD = FDEM.Problem3D_b(mesh,
                             sigma=surj1Dmap * sigma,
                             muMap=muMap,
                             Solver=Solver)
    prbFD.pair(surveyFD)
    std = 0.03
    surveyFD.makeSyntheticData(mtrue, std)
    surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-6

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

    # Inversion Directives    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.)

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

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

    dpredFD = surveyFD.dpred(moptFD)

    if plotIt:
        fig, ax = plt.subplots(1, 3, figsize=(10, 6))

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

        # Plot the conductivity model
        ax[0].semilogx(sigma[active], mesh.vectorCCz[active], 'k-', lw=2)
        ax[0].set_ylim(-500, 0)
        ax[0].set_xlim(5e-3, 1e-1)

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

        # Plot the permeability model
        ax[1].plot(mur[active], mesh.vectorCCz[active], 'k-', lw=2)
        ax[1].plot(moptFD, mesh.vectorCCz[active], 'b-', lw=2)
        ax[1].set_ylim(-500, 0)
        ax[1].set_xlim(0.5, 2.1)

        ax[1].set_xlabel('Relative Permeability', fontsize=fs)
        ax[1].set_ylabel('Depth (m)', fontsize=fs)
        ax[1].grid(which='both',
                   color='k',
                   alpha=0.5,
                   linestyle='-',
                   linewidth=0.2)
        ax[1].legend(['True', 'Predicted'], fontsize=fs, loc=4)

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

        ax[2].plot(freqs, -surveyFD.dobs, 'k-', lw=2)
        # ax[2].plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2)

        ax[2].loglog(freqs, -dpredFD, 'bo', ms=6)
        # ax[2].loglog(freqs, -dpredFD[1::2], 'b+', markeredgewidth=2., ms=10)

        # Labels, gridlines, etc
        ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2)
        ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2)

        ax[2].set_xlabel('Frequency (Hz)', fontsize=fs)
        ax[2].set_ylabel('Vertical magnetic field (-T)', fontsize=fs)

        # ax[2].legend(("Obs", "Pred"), fontsize=fs)
        ax[2].legend(("z-Obs (real)", "z-Pred (real)"), fontsize=fs)
        ax[2].set_xlim(freqs.max(), freqs.min())

        ax[0].set_title("(a) Conductivity Model", fontsize=fs)
        ax[1].set_title("(b) $\mu_r$ Model", fontsize=fs)
        ax[2].set_title("(c) FDEM observed vs. predicted", fontsize=fs)
        # ax[2].set_title("(c) TDEM observed vs. predicted", fontsize=fs)

        plt.tight_layout(pad=1.5)
Example #17
0
opt = Optimization.ProjectedGNCG(maxIter=25, lower=-np.inf,
                                 upper=np.inf, maxIterLS=20,
                                 maxIterCG=20, tolCG=1e-3)

# Define misfit function (obs-calc)
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.W = 1./survey.std

# Create the default L2 inverse problem from the above objects
invProb = InvProblem.BaseInvProblem(dmis, reg, opt)

# Specify how the initial beta is found
betaest = Directives.BetaEstimate_ByEig()

# Beta schedule for inversion
betaSchedule = Directives.BetaSchedule(coolingFactor=2., coolingRate=1)

# Target misfit to stop the inversion,
# try to fit as much as possible of the signal, we don't want to lose anything
targetMisfit = Directives.TargetMisfit(chifact=0.1)

# Put all the parts together
inv = Inversion.BaseInversion(invProb,
                              directiveList=[betaest, betaSchedule, targetMisfit])

# Run the equivalent source inversion
mstart = np.zeros(nC)
mrec = inv.run(mstart)

# Ouput result
Mesh.TensorMesh.writeModelUBC(mesh, work_dir + out_dir + "EquivalentSource.sus", surfMap*mrec)
Example #18
0
def run_inversion(
    m0,
    survey,
    actind,
    mesh,
    wires,
    std,
    eps,
    maxIter=15,
    beta0_ratio=1e0,
    coolingFactor=2,
    coolingRate=2,
    maxIterLS=20,
    maxIterCG=10,
    LSshorten=0.5,
    eta_lower=1e-5,
    eta_upper=1,
    tau_lower=1e-6,
    tau_upper=10.,
    c_lower=1e-2,
    c_upper=1.,
    is_log_tau=True,
    is_log_c=True,
    is_log_eta=True,
    mref=None,
    alpha_s=1e-4,
    alpha_x=1e0,
    alpha_y=1e0,
    alpha_z=1e0,
):
    """
    Run Spectral Spectral IP inversion
    """
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(survey.dobs) * std + eps
    dmisfit.W = 1. / uncert
    # Map for a regularization
    # Related to inversion

    # Set Upper and Lower bounds
    e = np.ones(actind.sum())

    if np.isscalar(eta_lower):
        eta_lower = e * eta_lower
    if np.isscalar(tau_lower):
        tau_lower = e * tau_lower
    if np.isscalar(c_lower):
        c_lower = e * c_lower

    if np.isscalar(eta_upper):
        eta_upper = e * eta_upper
    if np.isscalar(tau_upper):
        tau_upper = e * tau_upper
    if np.isscalar(c_upper):
        c_upper = e * c_upper

    if is_log_eta:
        eta_upper = np.log(eta_upper)
        eta_lower = np.log(eta_lower)

    if is_log_tau:
        tau_upper = np.log(tau_upper)
        tau_lower = np.log(tau_lower)

    if is_log_c:
        c_upper = np.log(c_upper)
        c_lower = np.log(c_lower)

    m_upper = np.r_[eta_upper, tau_upper, c_upper]
    m_lower = np.r_[eta_lower, tau_lower, c_lower]

    # Set up regularization
    reg_eta = Regularization.Tikhonov(mesh,
                                      mapping=wires.eta,
                                      indActive=actind)
    reg_tau = Regularization.Tikhonov(mesh,
                                      mapping=wires.tau,
                                      indActive=actind)

    reg_c = Regularization.Tikhonov(mesh, mapping=wires.c, indActive=actind)

    # Todo:

    reg_eta.alpha_s = alpha_s
    reg_tau.alpha_s = alpha_s
    reg_c.alpha_s = alpha_s

    reg_eta.alpha_x = alpha_x
    reg_tau.alpha_x = alpha_x
    reg_c.alpha_x = alpha_x

    reg_eta.alpha_y = alpha_y
    reg_tau.alpha_y = alpha_y
    reg_c.alpha_y = alpha_y

    reg_eta.alpha_z = alpha_z
    reg_tau.alpha_z = alpha_z
    reg_c.alpha_z = alpha_z

    reg = reg_eta + reg_tau + reg_c

    # Use Projected Gauss Newton scheme
    opt = Optimization.ProjectedGNCG(maxIter=maxIter,
                                     upper=m_upper,
                                     lower=m_lower,
                                     maxIterLS=maxIterLS,
                                     maxIterCG=maxIterCG,
                                     LSshorten=LSshorten)
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=coolingFactor,
                                   coolingRate=coolingRate)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio)
    target = Directives.TargetMisfit()

    directiveList = [beta, betaest, target]

    inv = Inversion.BaseInversion(invProb, directiveList=directiveList)
    opt.LSshorten = 0.5
    opt.remember('xc')

    # Run inversion
    mopt = inv.run(m0)
    return mopt, invProb.dpred
Example #19
0
    def run_inversion_cg(
        self,
        maxIter=60,
        m0=0.0,
        mref=0.0,
        percentage=5,
        floor=0.1,
        chifact=1,
        beta0_ratio=1.0,
        coolingFactor=1,
        coolingRate=1,
        alpha_s=1.0,
        alpha_x=1.0,
        use_target=False,
    ):
        survey, prob = self.get_problem_survey()
        survey.eps = percentage
        survey.std = floor
        survey.dobs = self.data.copy()
        self.uncertainty = percentage * abs(survey.dobs) * 0.01 + floor

        m0 = np.ones(self.M) * m0
        mref = np.ones(self.M) * mref
        reg = Regularization.Tikhonov(
            self.mesh, alpha_s=alpha_s, alpha_x=alpha_x, mref=mref
        )
        dmis = DataMisfit.l2_DataMisfit(survey)
        dmis.W = 1.0 / self.uncertainty

        opt = Optimization.InexactGaussNewton(maxIter=maxIter, maxIterCG=20)
        opt.remember("xc")
        opt.tolG = 1e-10
        opt.eps = 1e-10
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
        save = Directives.SaveOutputEveryIteration()
        beta_schedule = Directives.BetaSchedule(
            coolingFactor=coolingFactor, coolingRate=coolingRate
        )
        target = Directives.TargetMisfit(chifact=chifact)

        if use_target:
            directives = [
                Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio),
                beta_schedule,
                target,
                save,
            ]
        else:
            directives = [
                Directives.BetaEstimate_ByEig(beta0_ratio=beta0_ratio),
                beta_schedule,
                save,
            ]
        inv = Inversion.BaseInversion(invProb, directiveList=directives)
        mopt = inv.run(m0)
        model = opt.recall("xc")
        model.append(mopt)
        pred = []
        for m in model:
            pred.append(survey.dpred(m))
        return model, pred, save
Example #20
0
def run(plotIt=True):
    """
        FLOW: Richards: 1D: Inversion
        =============================

        The example shows an inversion of Richards equation in 1D with a
        heterogeneous hydraulic conductivity function.

        The haverkamp model is used with the same parameters as Celia1990_
        the boundary and initial conditions are also the same. The simulation
        domain is 40cm deep and is run for an hour with an exponentially
        increasing time step that has a maximum of one minute. The general
        setup of the experiment is an infiltration front that advances
        downward through the model over time.

        The model chosen is the saturated hydraulic conductivity inside
        the hydraulic conductivity function (using haverkamp). The initial
        model is chosen to be the background (1e-3 cm/s). The saturation data
        has 2% random Gaussian noise added.

        The figure shows the recovered saturated hydraulic conductivity
        next to the true model. The other two figures show the saturation
        field for the entire simulation for the true and recovered models.

        Rowan Cockett - 21/12/2016

        .. _Celia1990: http://www.webpages.uidaho.edu/ch/papers/Celia.pdf
    """

    M = Mesh.TensorMesh([np.ones(40)], x0='N')
    M.setCellGradBC('dirichlet')
    # We will use the haverkamp empirical model with parameters from Celia1990
    k_fun, theta_fun = Richards.Empirical.haverkamp(M,
                                                    A=1.1750e+06,
                                                    gamma=4.74,
                                                    alpha=1.6110e+06,
                                                    theta_s=0.287,
                                                    theta_r=0.075,
                                                    beta=3.96)

    # Here we are making saturated hydraulic conductivity
    # an exponential mapping to the model (defined below)
    k_fun.KsMap = Maps.ExpMap(nP=M.nC)

    # Setup the boundary and initial conditions
    bc = np.array([-61.5, -20.7])
    h = np.zeros(M.nC) + bc[0]
    prob = Richards.RichardsProblem(M,
                                    hydraulic_conductivity=k_fun,
                                    water_retention=theta_fun,
                                    boundary_conditions=bc,
                                    initial_conditions=h,
                                    do_newton=False,
                                    method='mixed',
                                    debug=False)
    prob.timeSteps = [(5, 25, 1.1), (60, 40)]

    # Create the survey
    locs = -np.arange(2, 38, 4.)
    times = np.arange(30, prob.timeMesh.vectorCCx[-1], 60)
    rxSat = Richards.SaturationRx(locs, times)
    survey = Richards.RichardsSurvey([rxSat])
    survey.pair(prob)

    # Create a simple model for Ks
    Ks = 1e-3
    mtrue = np.ones(M.nC) * np.log(Ks)
    mtrue[15:20] = np.log(5e-2)
    mtrue[20:35] = np.log(3e-3)
    mtrue[35:40] = np.log(1e-2)
    m0 = np.ones(M.nC) * np.log(Ks)

    # Create some synthetic data and fields
    stdev = 0.02  # The standard deviation for the noise
    Hs = prob.fields(mtrue)
    survey.makeSyntheticData(mtrue, std=stdev, f=Hs, force=True)

    # Setup a pretty standard inversion
    reg = Regularization.Tikhonov(M, alpha_s=1e-1)
    dmis = DataMisfit.l2_DataMisfit(survey)
    opt = Optimization.InexactGaussNewton(maxIter=20, maxIterCG=10)
    invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
    beta = Directives.BetaSchedule(coolingFactor=4)
    betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e2)
    target = Directives.TargetMisfit()
    dir_list = [beta, betaest, target]
    inv = Inversion.BaseInversion(invProb, directiveList=dir_list)

    mopt = inv.run(m0)

    Hs_opt = prob.fields(mopt)

    if plotIt:
        plt.figure(figsize=(14, 9))

        ax = plt.subplot(121)
        plt.semilogx(np.exp(np.c_[mopt, mtrue]), M.gridCC)
        plt.xlabel('Saturated Hydraulic Conductivity, $K_s$')
        plt.ylabel('Depth, cm')
        plt.semilogx([10**-3.9] * len(locs), locs, 'ro')
        plt.legend(('$m_{rec}$', '$m_{true}$', 'Data locations'), loc=4)

        ax = plt.subplot(222)
        mesh2d = Mesh.TensorMesh([prob.timeMesh.hx / 60, prob.mesh.hx], '0N')
        sats = [theta_fun(_) for _ in Hs]
        clr = mesh2d.plotImage(np.c_[sats][1:, :], ax=ax)
        cmap0 = matplotlib.cm.RdYlBu_r
        clr[0].set_cmap(cmap0)
        c = plt.colorbar(clr[0])
        c.set_label('Saturation $\\theta$')
        plt.xlabel('Time, minutes')
        plt.ylabel('Depth, cm')
        plt.title('True saturation over time')

        ax = plt.subplot(224)
        mesh2d = Mesh.TensorMesh([prob.timeMesh.hx / 60, prob.mesh.hx], '0N')
        sats = [theta_fun(_) for _ in Hs_opt]
        clr = mesh2d.plotImage(np.c_[sats][1:, :], ax=ax)
        cmap0 = matplotlib.cm.RdYlBu_r
        clr[0].set_cmap(cmap0)
        c = plt.colorbar(clr[0])
        c.set_label('Saturation $\\theta$')
        plt.xlabel('Time, minutes')
        plt.ylabel('Depth, cm')
        plt.title('Recovered saturation over time')

        plt.tight_layout()