def solve(self): # Tikhonov Inversion #################### # Initial model values m0 = np.median(self.ln_sigback) * np.ones(self.mapping.nP) # Misfit functional dmis = DataMisfit.l2_DataMisfit(self.survey.simpeg_survey) # Regularization functional regT = Regularization.Simple(self.mesh_core_XZ) # Personal preference for this solver with a Jacobi preconditioner opt = Optimization.ProjectedGNCG(maxIter=10, lower=-10, upper=10, maxIterLS=20, maxIterCG=30, tolCG=1e-4) # 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)
def setUp(self): aSpacing = 2.5 nElecs = 5 surveySize = nElecs * aSpacing - aSpacing cs = surveySize / nElecs / 4 mesh = Mesh.TensorMesh( [ [(cs, 10, -1.3), (cs, surveySize / cs), (cs, 10, 1.3)], [(cs, 3, -1.3), (cs, 3, 1.3)], # [(cs, 5, -1.3), (cs, 10)] ], 'CN') srcList = DC.Utils.WennerSrcList(nElecs, aSpacing, in2D=True) survey = DC.Survey(srcList) problem = DC.Problem3D_CC(mesh, rhoMap=Maps.IdentityMap(mesh)) problem.pair(survey) mSynth = np.ones(mesh.nC) survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.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
def setUp(self): cs = 12.5 hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy], x0="CN") x = np.linspace(-135, 250., 20) M = Utils.ndgrid(x - 12.5, np.r_[0.]) N = Utils.ndgrid(x + 12.5, np.r_[0.]) A0loc = np.r_[-150, 0.] A1loc = np.r_[-130, 0.] rxloc = [np.c_[M, np.zeros(20)], np.c_[N, np.zeros(20)]] rx = DC.Rx.Dipole_ky(M, N) src0 = DC.Src.Pole([rx], A0loc) src1 = DC.Src.Pole([rx], A1loc) survey = DC.Survey_ky([src0, src1]) problem = DC.Problem2D_N(mesh, mapping=[('rho', Maps.IdentityMap(mesh))]) problem.pair(survey) mSynth = np.ones(mesh.nC) * 1. survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e0) 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
def MagneticsDiffSecondaryInv(mesh, model, data, **kwargs): """ Inversion module for MagneticsDiffSecondary """ from SimPEG import Optimization, Regularization, Parameters, ObjFunction, Inversion prob = Simulation3DDifferential(mesh, survey=data, mu=model) miter = kwargs.get("maxIter", 10) # Create an optimization program opt = Optimization.InexactGaussNewton(maxIter=miter) opt.bfgsH0 = Solver(sp.identity(model.nP), flag="D") # Create a regularization program reg = Regularization.Tikhonov(model) # Create an objective function beta = Parameters.BetaSchedule(beta0=1e0) obj = ObjFunction.BaseObjFunction(prob, reg, beta=beta) # Create an inversion object inv = Inversion.BaseInversion(obj, opt) return inv, reg
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 setUp(self): time = np.logspace(-3, 0, 21) n_loc = 5 wires = Maps.Wires(('eta', n_loc), ('tau', n_loc), ('c', n_loc)) taumap = Maps.ExpMap(nP=n_loc) * wires.tau etamap = Maps.ExpMap(nP=n_loc) * wires.eta cmap = Maps.ExpMap(nP=n_loc) * wires.c survey = SEMultiSurvey(time=time, locs=np.zeros((n_loc, 3)), n_pulse=0) mesh = Mesh.TensorMesh([np.ones(int(n_loc * 3))]) prob = SEMultiInvProblem(mesh, etaMap=etamap, tauMap=taumap, cMap=cmap) prob.pair(survey) eta0, tau0, c0 = 0.1, 10., 0.5 m0 = np.log(np.r_[eta0 * np.ones(n_loc), tau0 * np.ones(n_loc), c0 * np.ones(n_loc)]) survey.makeSyntheticData(m0) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=0.) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = prob self.survey = survey self.m0 = m0 self.dmis = dmis self.mesh = mesh
# 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) # %% STEP 2: COMPUTE AMPLITUDE DATA # Now that we have an equialent source layer, we can forward model alh three # components of the field and add them up: |B| = ( Bx**2 + Bx**2 + Bx**2 )**0.5 # Won't store the sensitivity and output 'xyz' data. prob.forwardOnly = True
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')
def run(plotIt=True, cleanAfterRun=True): # Start by downloading files from the remote repository # directory where the downloaded files are url = "https://storage.googleapis.com/simpeg/Chile_GRAV_4_Miller/Chile_GRAV_4_Miller.tar.gz" downloads = download(url, overwrite=True) basePath = downloads.split(".")[0] # unzip the tarfile tar = tarfile.open(downloads, "r") tar.extractall() tar.close() input_file = basePath + os.path.sep + 'LdM_input_file.inp' # %% User input # Plotting parameters, max and min densities in g/cc vmin = -0.6 vmax = 0.6 # weight exponent for default weighting wgtexp = 3. # %% # Read in the input file which included all parameters at once # (mesh, topo, model, survey, inv param, etc.) driver = PF.GravityDriver.GravityDriver_Inv(input_file) # %% # Now we need to create the survey and model information. # Access the mesh and survey information mesh = driver.mesh survey = driver.survey # define gravity survey locations rxLoc = survey.srcField.rxList[0].locs # define gravity data and errors d = survey.dobs wd = survey.std # Get the active cells active = driver.activeCells nC = len(active) # Number of active cells # Create active map to go from reduce set to full activeMap = Maps.InjectActiveCells(mesh, active, -100) # Create static map static = driver.staticCells dynamic = driver.dynamicCells staticCells = Maps.InjectActiveCells(None, dynamic, driver.m0[static], nC=nC) mstart = driver.m0[dynamic] # Get index of the center midx = int(mesh.nCx / 2) # %% # Now that we have a model and a survey we can build the linear system ... # Create the forward model operator prob = PF.Gravity.GravityIntegral(mesh, rhoMap=staticCells, actInd=active) prob.solverOpts['accuracyTol'] = 1e-4 # Pair the survey and problem survey.pair(prob) # Apply depth weighting wr = PF.Magnetics.get_dist_wgt(mesh, rxLoc, active, wgtexp, np.min(mesh.hx) / 4.) wr = wr**2. # %% Create inversion objects reg = Regularization.Sparse(mesh, indActive=active, mapping=staticCells, gradientType='total') reg.mref = driver.mref[dynamic] reg.cell_weights = wr * mesh.vol[active] reg.norms = np.c_[0., 1., 1., 1.] # reg.norms = driver.lpnorms # Specify how the optimization will proceed opt = Optimization.ProjectedGNCG(maxIter=20, lower=driver.bounds[0], upper=driver.bounds[1], maxIterLS=10, maxIterCG=20, tolCG=1e-3) # Define misfit function (obs-calc) dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / wd # 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(beta0_ratio=1e-2) # IRLS sets up the Lp inversion problem # Set the eps parameter parameter in Line 11 of the # input file based on the distribution of model (DEFAULT = 95th %ile) IRLS = Directives.Update_IRLS(f_min_change=1e-4, maxIRLSiter=40, beta_tol=5e-1) # Preconditioning refreshing for each IRLS iteration update_Jacobi = Directives.UpdatePreconditioner() # Create combined the L2 and Lp problem inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi, betaest]) # %% # Run L2 and Lp inversion mrec = inv.run(mstart) if cleanAfterRun: os.remove(downloads) shutil.rmtree(basePath) # %% if plotIt: # Plot observed data PF.Magnetics.plot_obs_2D(rxLoc, d, 'Observed Data') # %% # Write output model and data files and print misft stats. # reconstructing l2 model mesh with air cells and active dynamic cells L2out = activeMap * invProb.l2model # reconstructing lp model mesh with air cells and active dynamic cells Lpout = activeMap * mrec # %% # Plot out sections and histograms of the smooth l2 model. # The ind= parameter is the slice of the model from top down. yslice = midx + 1 L2out[L2out == -100] = np.nan # set "air" to nan plt.figure(figsize=(10, 7)) plt.suptitle('Smooth Inversion: Depth weight = ' + str(wgtexp)) ax = plt.subplot(221) dat1 = mesh.plotSlice(L2out, ax=ax, normal='Z', ind=-16, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.plot(np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]), c='gray', linestyle='--') plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color='k', s=1) plt.title('Z: ' + str(mesh.vectorCCz[-16]) + ' m') plt.xlabel('Easting (m)') plt.ylabel('Northing (m)') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat1[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4)) cb.set_label('Density (g/cc$^3$)') ax = plt.subplot(222) dat = mesh.plotSlice(L2out, ax=ax, normal='Z', ind=-27, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.plot(np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]), c='gray', linestyle='--') plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color='k', s=1) plt.title('Z: ' + str(mesh.vectorCCz[-27]) + ' m') plt.xlabel('Easting (m)') plt.ylabel('Northing (m)') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat1[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4)) cb.set_label('Density (g/cc$^3$)') ax = plt.subplot(212) mesh.plotSlice(L2out, ax=ax, normal='Y', ind=yslice, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.title('Cross Section') plt.xlabel('Easting(m)') plt.ylabel('Elevation') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat1[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4), cmap='bwr') cb.set_label('Density (g/cc$^3$)') # %% # Make plots of Lp model yslice = midx + 1 Lpout[Lpout == -100] = np.nan # set "air" to nan plt.figure(figsize=(10, 7)) plt.suptitle('Compact Inversion: Depth weight = ' + str(wgtexp) + ': $\epsilon_p$ = ' + str(round(reg.eps_p, 1)) + ': $\epsilon_q$ = ' + str(round(reg.eps_q, 2))) ax = plt.subplot(221) dat = mesh.plotSlice(Lpout, ax=ax, normal='Z', ind=-16, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.plot(np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]), c='gray', linestyle='--') plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color='k', s=1) plt.title('Z: ' + str(mesh.vectorCCz[-16]) + ' m') plt.xlabel('Easting (m)') plt.ylabel('Northing (m)') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4)) cb.set_label('Density (g/cc$^3$)') ax = plt.subplot(222) dat = mesh.plotSlice(Lpout, ax=ax, normal='Z', ind=-27, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.plot(np.array([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), np.array([mesh.vectorCCy[yslice], mesh.vectorCCy[yslice]]), c='gray', linestyle='--') plt.scatter(rxLoc[0:, 0], rxLoc[0:, 1], color='k', s=1) plt.title('Z: ' + str(mesh.vectorCCz[-27]) + ' m') plt.xlabel('Easting (m)') plt.ylabel('Northing (m)') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4)) cb.set_label('Density (g/cc$^3$)') ax = plt.subplot(212) dat = mesh.plotSlice(Lpout, ax=ax, normal='Y', ind=yslice, clim=(vmin, vmax), pcolorOpts={'cmap': 'bwr'}) plt.title('Cross Section') plt.xlabel('Easting (m)') plt.ylabel('Elevation (m)') plt.gca().set_aspect('equal', adjustable='box') cb = plt.colorbar(dat[0], orientation="vertical", ticks=np.linspace(vmin, vmax, 4)) cb.set_label('Density (g/cc$^3$)')
regmap = Maps.IdentityMap(nP=m0.size) survey.std = perc survey.eps = floor survey.dobs = dobs dmisfit = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Simple(mesh, mapping=regmap, indActive=~airind) opt = Optimization.InexactGaussNewton(maxIter=20) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Create an inversion object beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) save = Directives.SaveOutputEveryIteration() save_model = Directives.SaveModelEveryIteration() target = Directives.TargetMisfit() inv = Inversion.BaseInversion( invProb, directiveList=[beta, betaest, save, save_model, target]) reg.alpha_s = 1e-2 reg.alpha_x = 1. reg.alpha_y = 1. reg.alpha_z = 1. problem.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 mopt = inv.run(m0) sigopt = mapping * mopt np.save("sigest", sigopt) np.save("dpred", invProb.dpred)
Directives.SaveUBCPredictedEveryIteration( survey=survey, fileName=outDir + input_dict["inversion_type"], format=input_dict["inversion_type"] ) ) invProb_idx = len(directiveList) - 1 directiveList.append( Directives.SaveOutputDictEveryIteration() ) inversion_output_idx = len(directiveList) - 1 # Put all the parts together inv = Inversion.BaseInversion( invProb, directiveList=directiveList ) # SimPEG reports half phi_d, so we scale to match print( "Start Inversion: " + inversion_style + "\nTarget Misfit: %.2e (%.0f data with chifact = %g)" % ( 0.5 * target_chi * len(survey.std), len(survey.std), target_chi ) ) # Run the inversion mrec = inv.run(mstart) dpred = directiveList[invProb_idx].invProb.dpred
def setUp(self): cs = 25. 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 = Mesh.TensorMesh([hx, hy, hz], x0="CCC") blkind0 = Utils.ModelBuilder.getIndicesSphere( np.r_[-100., -100., -200.], 75., mesh.gridCC) blkind1 = Utils.ModelBuilder.getIndicesSphere(np.r_[100., 100., -200.], 75., mesh.gridCC) sigma = np.ones(mesh.nC) * 1e-2 airind = mesh.gridCC[:, 2] > 0. sigma[airind] = 1e-8 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma) * 1. eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.01 actmapeta = Maps.InjectActiveCells(mesh, ~airind, 0.) actmaptau = Maps.InjectActiveCells(mesh, ~airind, 1.) x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x - 25., y, np.r_[0.]) N = Utils.ndgrid(x + 25., y, np.r_[0.]) times = np.arange(10) * 1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) colemap = [("eta", Maps.IdentityMap(mesh) * actmapeta), ("taui", Maps.IdentityMap(mesh) * actmaptau)] problem = SIP.Problem3D_N(mesh, sigma=sigma, mapping=colemap) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta[~airind], 1. / tau[~airind]] survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) regmap = Maps.IdentityMap(nP=int(mSynth[~airind].size * 2)) reg = SIP.MultiRegularization(mesh, mapping=regmap, nModels=2, indActive=~airind) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.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
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]) plt.gca().set_xlim([-10., 10.]) plt.gca().set_ylim([-10., 0.]) np.save('./finalresult', msimple) #plt.show()
def setUp(self): cs = 25. 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 = Mesh.TensorMesh([hx, hy, hz], x0="CCC") blkind0 = Utils.ModelBuilder.getIndicesSphere( np.r_[-100., -100., -200.], 75., mesh.gridCC ) blkind1 = Utils.ModelBuilder.getIndicesSphere( np.r_[100., 100., -200.], 75., mesh.gridCC ) sigma = np.ones(mesh.nC)*1e-2 airind = mesh.gridCC[:, 2] > 0. sigma[airind] = 1e-8 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma) * 1. 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.) actmaptau = Maps.InjectActiveCells(mesh, ~airind, 1.) actmapc = Maps.InjectActiveCells(mesh, ~airind, 1.) x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] y = mesh.vectorCCy[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x-25., y, np.r_[0.]) N = Utils.ndgrid(x+25., y, np.r_[0.]) times = np.arange(10)*1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) wires = Maps.Wires(('eta', actmapeta.nP), ('taui', actmaptau.nP), ('c', actmapc.nP)) problem = SIP.Problem3D_N( mesh, sigma=sigma, etaMap=actmapeta*wires.eta, tauiMap=actmaptau*wires.taui, cMap=actmapc*wires.c, actinds=~airind, storeJ = True, verbose=False ) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta[~airind], 1./tau[~airind], c[~airind]] survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) dmis = DataMisfit.l2_DataMisfit(survey) reg_eta = Regularization.Simple(mesh, mapping=wires.eta, indActive=~airind) reg_taui = Regularization.Simple(mesh, mapping=wires.taui, indActive=~airind) reg_c = Regularization.Simple(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 = InvProblem.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
tolCG=1e-4) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) # A list of directive to control the inverson betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied # Use pick a treshold parameter empirically based on the distribution of # model parameters IRLS = Directives.Update_IRLS(f_min_change=1e-3, maxIRLSiter=0, beta_tol=5e-1) # Pre-conditioner update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi, betaest]) # Run the inversion m0 = np.ones(3 * nC) * 1e-4 # Starting model mrec_MVIC = inv.run(m0) ############################################################### # Sparse Vector Inversion # ----------------------- # # Re-run the MVI in spherical domain so we can impose # sparsity in the vectors. # # mstart = Utils.matutils.cartesian2spherical(
reg.cell_weights = wr # reg.norms = [0, 1, 1, 1] # reg.eps_p, reg.eps_q = 1e-3, 1e-3 mesh.writeModelUBC('J1.dat', actvMap * wr) mesh.writeModelUBC('J.dat', actvMap * np.sum(prob.G**2., axis=0)) # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=100, lower=0., upper=1., maxIterLS=20, maxIterCG=10, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(globalMisfit, reg, opt) betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied # Use pick a treshold parameter empirically based on the distribution of # model parameters IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=3) update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, betaest, update_Jacobi]) # Run the inversion m0 = np.ones(nC) * 1e-4 # Starting model mrec = inv.run(m0) mesh.writeModelUBC('Mrec.sus', actvMap * mrec)
def setUp(self): cs = 25. 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)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN") blkind0 = Utils.ModelBuilder.getIndicesSphere( np.r_[-100., -100., -200.], 75., mesh.gridCC ) blkind1 = Utils.ModelBuilder.getIndicesSphere( np.r_[100., 100., -200.], 75., mesh.gridCC ) sigma = np.ones(mesh.nC) * 1e-2 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma) * 1. eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.01 x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] y = mesh.vectorCCy[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x-25., y, np.r_[0.]) N = Utils.ndgrid(x+25., y, np.r_[0.]) times = np.arange(10)*1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC)) problem = SIP.Problem3D_CC( mesh, rho=1./sigma, etaMap=wires.eta, tauiMap=wires.taui, storeJ = True ) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta, 1./tau] problem.model = mSynth survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton( maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6 ) invProb = InvProblem.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
IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=1, beta_tol=0.25, maxIRLSiter=max_IRLS_iter, chifact_target=target_chi, betaSearch=False) # Save model saveDict = Directives.SaveOutputEveryIteration(save_txt=False) saveIt = Directives.SaveUBCModelEveryIteration( mapping=activeCellsMap, fileName=outDir + input_dict["inversion_type"].lower() + "_C", vector=input_dict["inversion_type"].lower()[0:3] == 'mvi') # Put all the parts together inv = Inversion.BaseInversion( invProb, directiveList=[saveIt, saveDict, betaest, IRLS, update_Jacobi]) # SimPEG reports half phi_d, so we scale to matrch print("Start Inversion\nTarget Misfit: %.2e (%.0f data with chifact = %g)" % (0.5 * target_chi * len(survey.std), len(survey.std), target_chi)) # Run the inversion mrec = inv.run(mstart) print("Target Misfit: %.3e (%.0f data with chifact = %g)" % (0.5 * target_chi * len(survey.std), len(survey.std), target_chi)) print("Final Misfit: %.3e" % (0.5 * np.sum( ((survey.dobs - invProb.dpred) / survey.std)**2.))) if show_graphics: # Plot convergence curves
def run(plotIt=True): nC = 40 de = 1. h = np.ones(nC) * de / nC M = Mesh.TensorMesh([h, h]) y = np.linspace(M.vectorCCy[0], M.vectorCCx[-1], int(np.floor(nC / 4))) rlocs = np.c_[0 * y + 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 ] # phi model phi0 = 0 phi1 = 0.65 phitrue = Utils.ModelBuilder.defineBlock(M.gridCC, [0.4, 0.6], [0.6, 0.4], [phi1, phi0]) knownVolume = np.sum(phitrue * M.vol) print('True Volume: {}'.format(knownVolume)) # Set up true conductivity model and plot the model transform sigma0 = np.exp(1) sigma1 = 1e4 if plotIt: fig, ax = plt.subplots(1, 1) sigmaMapTest = Maps.SelfConsistentEffectiveMedium(nP=1000, sigma0=sigma0, sigma1=sigma1, rel_tol=1e-1, maxIter=150) testphis = np.linspace(0., 1., 1000) sigetest = sigmaMapTest * testphis ax.semilogy(testphis, sigetest) ax.set_title('Model Transform') ax.set_xlabel('$\\varphi$') ax.set_ylabel('$\sigma$') sigmaMap = Maps.SelfConsistentEffectiveMedium(M, sigma0=sigma0, sigma1=sigma1) # scale the slowness so it is on a ~linear scale slownessMap = Maps.LogMap(M) * sigmaMap # set up the true sig model and log model dobs sigtrue = sigmaMap * phitrue # modt = Model.BaseModel(M); slownesstrue = slownessMap * phitrue # true model (m = log(sigma)) # set up the problem and survey survey = StraightRay.Survey(srcList) problem = StraightRay.Problem(M, slownessMap=slownessMap) problem.pair(survey) if plotIt: fig, ax = plt.subplots(1, 1) cb = plt.colorbar(M.plotImage(phitrue, ax=ax)[0], ax=ax) survey.plot(ax=ax) cb.set_label('$\\varphi$') # get observed data dobs = survey.makeSyntheticData(phitrue, std=0.03, force=True) dpred = survey.dpred(np.zeros(M.nC)) # objective function pieces reg = Regularization.Tikhonov(M) dmis = DataMisfit.l2_DataMisfit(survey) dmisVol = Volume(mesh=M, knownVolume=knownVolume) beta = 0.25 maxIter = 15 # without the volume regularization opt = Optimization.ProjectedGNCG(maxIter=maxIter, lower=0.0, upper=1.0) opt.remember('xc') invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=beta) inv = Inversion.BaseInversion(invProb) mopt1 = inv.run(np.zeros(M.nC) + 1e-16) print('\nTotal recovered volume (no vol misfit term in inversion): ' '{}'.format(dmisVol(mopt1))) # with the volume regularization vol_multiplier = 9e4 reg2 = reg dmis2 = dmis + vol_multiplier * dmisVol opt2 = Optimization.ProjectedGNCG(maxIter=maxIter, lower=0.0, upper=1.0) opt2.remember('xc') invProb2 = InvProblem.BaseInvProblem(dmis2, reg2, opt2, beta=beta) inv2 = Inversion.BaseInversion(invProb2) mopt2 = inv2.run(np.zeros(M.nC) + 1e-16) print('\nTotal volume (vol misfit term in inversion): {}'.format( dmisVol(mopt2))) # plot results if plotIt: fig, ax = plt.subplots(1, 1) ax.plot(dobs) ax.plot(dpred) ax.plot(survey.dpred(mopt1), 'o') ax.plot(survey.dpred(mopt2), 's') ax.legend(['dobs', 'dpred0', 'dpred w/o Vol', 'dpred with Vol']) fig, ax = plt.subplots(1, 3, figsize=(16, 4)) cb0 = plt.colorbar(M.plotImage(phitrue, ax=ax[0])[0], ax=ax[0]) cb1 = plt.colorbar(M.plotImage(mopt1, ax=ax[1])[0], ax=ax[1]) cb2 = plt.colorbar(M.plotImage(mopt2, ax=ax[2])[0], ax=ax[2]) for cb in [cb0, cb1, cb2]: cb.set_clim([0., phi1]) ax[0].set_title('true, vol: {:1.3e}'.format(knownVolume)) ax[1].set_title('recovered(no Volume term), vol: {:1.3e} '.format( dmisVol(mopt1))) ax[2].set_title('recovered(with Volume term), vol: {:1.3e} '.format( dmisVol(mopt2))) plt.tight_layout()
def setUp(self): ndv = -100 # Create a mesh dx = 5. 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)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC') # Get index of the center midx = int(mesh.nCx/2) midy = int(mesh.nCy/2) # Lets create a simple Gaussian topo and set the active cells [xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy) zz = -np.exp((xx**2 + yy**2) / 75**2) + 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(mesh, topo, 'N') actv = np.asarray([inds for inds, elem in enumerate(actv, 1) if elem], dtype=int) - 1 # Create active map to go from reduce space to full actvMap = Maps.InjectActiveCells(mesh, actv, -100) nC = len(actv) # Create and array of observation points xr = np.linspace(-20., 20., 20) yr = np.linspace(-20., 20., 20) X, Y = np.meshgrid(xr, yr) # Move the observation points 5m above the topo Z = -np.exp((X**2 + Y**2) / 75**2) + mesh.vectorNz[-1] + 5. # Create a MAGsurvey locXYZ = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)] rxLoc = PF.BaseGrav.RxObs(locXYZ) srcField = PF.BaseGrav.SrcField([rxLoc]) survey = PF.BaseGrav.LinearSurvey(srcField) # We can now create a density model and generate data # Here a simple block in half-space model = np.zeros((mesh.nCx, mesh.nCy, 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(mesh, actv, ndv) # Create reduced identity map idenMap = Maps.IdentityMap(nP=nC) # Create the forward model operator prob = PF.Gravity.GravityIntegral( mesh, rhoMap=idenMap, actInd=actv ) # Pair the survey and problem survey.pair(prob) # Compute linear forward operator and compute some data d = prob.fields(self.model) # Add noise and uncertainties (1nT) data = d + np.random.randn(len(d))*0.001 wd = np.ones(len(data))*.001 survey.dobs = data survey.std = wd # PF.Gravity.plot_obs_2D(survey.srcField.rxList[0].locs, d=data) # Create sensitivity weights from our linear forward operator wr = PF.Magnetics.get_dist_wgt(mesh, locXYZ, actv, 2., 2.) wr = wr**2. # Create a regularization reg = Regularization.Sparse(mesh, indActive=actv, mapping=idenMap) reg.cell_weights = wr reg.norms = [0, 1, 1, 1] reg.eps_p, reg.eps_q = 5e-2, 1e-2 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1/wd # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=100, lower=-1., upper=1., maxIterLS=20, maxIterCG=10, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e+8) # Here is where the norms are applied IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=3) update_Jacobi = Directives.Update_lin_PreCond(mapping=idenMap) self.inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi])
reg_t.cell_weights = wires.third * wr reg = reg_p + reg_s + reg_t # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=30, lower=-10., upper=10., maxIterCG=20, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) betaest = Directives.BetaEstimate_ByEig() betaCool = Directives.BetaSchedule(coolingFactor=2., coolingRate=1) update_Jacobi = Directives.UpdatePreCond() targetMisfit = Directives.TargetMisfit() saveModel = Directives.SaveUBCModelEveryIteration(mapping=actvMap) saveModel.fileName = work_dir + out_dir + 'CMI_pst' inv = Inversion.BaseInversion( invProb, directiveList=[betaest, update_Jacobi, betaCool, targetMisfit, saveModel]) mstart = np.ones(3 * len(actv)) * 1e-4 mrec = inv.run(mstart) PF.Magnetics.writeUBCobs(work_dir + out_dir + 'CMI.pre', survey, invProb.dpred)
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 setUp(self): np.random.seed(0) # Define the inducing field parameter H0 = (50000, 90, 0) # Create a mesh dx = 5. 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)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC') # Get index of the center midx = int(mesh.nCx / 2) midy = int(mesh.nCy / 2) # Lets create a simple Gaussian topo and set the active cells [xx, yy] = np.meshgrid(mesh.vectorNx, mesh.vectorNy) zz = -np.exp((xx**2 + yy**2) / 75**2) + 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(mesh, topo, 'N') actv = np.asarray([inds for inds, elem in enumerate(actv, 1) if elem], dtype=int) - 1 # Create active map to go from reduce space to full actvMap = Maps.InjectActiveCells(mesh, actv, -100) nC = len(actv) # Create and array of observation points xr = np.linspace(-20., 20., 20) yr = np.linspace(-20., 20., 20) X, Y = np.meshgrid(xr, yr) # Move the observation points 5m above the topo Z = -np.exp((X**2 + Y**2) / 75**2) + mesh.vectorNz[-1] + 5. # Create a MAGsurvey rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)] rxLoc = PF.BaseMag.RxObs(rxLoc) srcField = PF.BaseMag.SrcField([rxLoc], param=H0) survey = PF.BaseMag.LinearSurvey(srcField) # We can now create a susceptibility model and generate data # Here a simple block in half-space model = np.zeros((mesh.nCx, mesh.nCy, mesh.nCz)) model[(midx - 2):(midx + 2), (midy - 2):(midy + 2), -6:-2] = 0.02 model = Utils.mkvc(model) self.model = model[actv] # Create active map to go from reduce set to full actvMap = Maps.InjectActiveCells(mesh, actv, -100) # Creat reduced identity map idenMap = Maps.IdentityMap(nP=nC) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=idenMap, actInd=actv) # Pair the survey and problem survey.pair(prob) # Compute linear forward operator and compute some data d = prob.fields(self.model) # Add noise and uncertainties (1nT) data = d + np.random.randn(len(d)) wd = np.ones(len(data)) * 1. survey.dobs = data survey.std = wd # Create sensitivity weights from our linear forward operator wr = np.sum(prob.G**2., axis=0)**0.5 wr = (wr / np.max(wr)) # Create a regularization reg = Regularization.Sparse(mesh, indActive=actv, mapping=idenMap) reg.cell_weights = wr reg.norms = np.c_[0, 0, 0, 0] reg.gradientType = 'component' # reg.eps_p, reg.eps_q = 1e-3, 1e-3 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1 / wd # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=100, lower=0., upper=1., maxIterLS=20, maxIterCG=10, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied IRLS = Directives.Update_IRLS(f_min_change=1e-4, minGNiter=1) update_Jacobi = Directives.UpdatePreconditioner() self.inv = Inversion.BaseInversion( invProb, directiveList=[IRLS, betaest, update_Jacobi])
upper=10, maxIterLS=20, maxIterCG=30, tolCG=1e-4) opt.remember('xc') invProb = InvProblem.BaseInvProblem(dmis, regT, opt) beta = Directives.BetaEstimate_ByEig(beta0_ratio=1.) Target = Directives.TargetMisfit() betaSched = Directives.BetaSchedule(coolingFactor=5., coolingRate=2) updateSensW = Directives.UpdateSensitivityWeights(threshold=1e-3) update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion( invProb, directiveList=[beta, Target, betaSched, updateSensW, update_Jacobi]) minv = inv.run(m0) # Final Plot ############ fig, ax = plt.subplots(1, 2, figsize=(12, 5)) ax = Utils.mkvc(ax) cyl0v = getCylinderPoints(x0, z0, r0) cyl1v = getCylinderPoints(x1, z1, r1) clim = [(mtrue[actind]).min(), (mtrue[actind]).max()]
alpha_y=1., alpha_z=1.) # Optimization Scheme opt = Optimization.InexactGaussNewton(maxIter=10) # Form the problem opt.remember('xc') invProb = InvProblem.BaseInvProblem(dmis, regT, opt) # Directives for Inversions beta = Directives.BetaEstimate_ByEig(beta0_ratio=1e+1) Target = Directives.TargetMisfit() betaSched = Directives.BetaSchedule(coolingFactor=5., coolingRate=2) inv = Inversion.BaseInversion(invProb, directiveList=[beta, Target, betaSched]) # Run Inversion minv = inv.run(m0) # Final Plot ############ fig, ax = plt.subplots(2, 2, figsize=(12, 6)) ax = Utils.mkvc(ax) cyl0v = getCylinderPoints(x0, z0, r0) cyl1v = getCylinderPoints(x1, z1, r1) cyl0h = getCylinderPoints(x0, y0, r0) cyl1h = getCylinderPoints(x1, y1, r1)
upper=10., maxIterCG=20, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(ComboMisfit, reg, opt) betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=1) update_Jacobi = Directives.UpdateJacobiPrecond() targetMisfit = Directives.TargetMisfit() saveModel = Directives.SaveUBCModelEveryIteration(mapping=actvMap) saveModel.fileName = work_dir + out_dir + 'GRAV' inv = Inversion.BaseInversion( invProb, directiveList=[betaest, IRLS, update_Jacobi, saveModel]) mrec = inv.run(mstart) if isinstance(mesh, Mesh.TreeMesh): Mesh.TreeMesh.writeUBC(mesh, work_dir + out_dir + 'OctreeMesh.msh', models={ work_dir + out_dir + 'GRAV_Octree_l2.den': actvMap * invProb.l2model }) else: mesh.writeModelUBC(mesh, work_dir + out_dir + 'GRAV_l2.den', actvMap * invProb.l2model) # Get predicted data for each tile and write full predicted to file
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
# LIST OF DIRECTIVES # betaest = Directives.BetaEstimate_ByEig() IRLS = Directives.Update_IRLS(f_min_change=1e-6, minGNiter=2, beta_tol=1e-2, coolingRate=2) update_SensWeight = Directives.UpdateSensWeighting() update_Jacobi = Directives.UpdatePreCond() ProjSpherical = Directives.ProjSpherical() JointAmpMVI = Directives.JointAmpMVI() betaest = Directives.BetaEstimate_ByEig() #saveModel = Directives.SaveUBCVectorsEveryIteration(mapping=actvMap, # saveComp=True, # spherical=True) inv = Inversion.BaseInversion(invProb, directiveList=[betaest, JointAmpMVI, IRLS, update_SensWeight, update_Jacobi]) # Run JOINT mrec = inv.run(mstart) #NOTE - Would like to have dpred working on both surveys dpred = invProb.getFields(mrec) print('Amplitude Final phi_d: ' + str(dmis_amp(mrec))) print('MVI Final phi_d: ' + str(dmis_MVI(mrec))) #%% Plot models from matplotlib.patches import Rectangle contours = [0.01] xlim = [-60,60]
def resolve_1Dinversions(mesh, dobs, src_height, freqs, m0, mref, mapping, std=0.08, floor=1e-14, rxOffset=7.86): """ Perform a single 1D inversion for a RESOLVE sounding for Horizontal Coplanar Coil data (both real and imaginary). :param discretize.CylMesh mesh: mesh used for the forward simulation :param numpy.array dobs: observed data :param float src_height: height of the source above the ground :param numpy.array freqs: frequencies :param numpy.array m0: starting model :param numpy.array mref: reference model :param Maps.IdentityMap mapping: mapping that maps the model to electrical conductivity :param float std: percent error used to construct the data misfit term :param float floor: noise floor used to construct the data misfit term :param float rxOffset: offset between source and receiver. """ # ------------------- Forward Simulation ------------------- # # set up the receivers bzr = EM.FDEM.Rx.Point_bSecondary(np.array([[rxOffset, 0., src_height]]), orientation='z', component='real') bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., src_height]]), orientation='z', component='imag') # source location srcLoc = np.array([0., 0., src_height]) srcList = [ EM.FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs ] # construct a forward simulation survey = EM.FDEM.Survey(srcList) prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=PardisoSolver) prb.pair(survey) # ------------------- Inversion ------------------- # # data misfit term survey.dobs = dobs dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = abs(dobs) * std + floor dmisfit.W = 1. / uncert # regularization regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) reg.mref = mref # optimization opt = Optimization.InexactGaussNewton(maxIter=10) # statement of the inverse problem invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion directives and parameters target = Directives.TargetMisfit() inv = Inversion.BaseInversion(invProb, directiveList=[target]) invProb.beta = 2. # Fix beta in the nonlinear iterations reg.alpha_s = 1e-3 reg.alpha_x = 1. prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') # run the inversion mopt = inv.run(m0) return mopt, invProb.dpred, survey.dobs
def setUp(self): np.random.seed(0) H0 = (50000., 90., 0.) # The magnetization is set along a different # direction (induced + remanence) M = np.array([45., 90.]) # Create grid of points for topography # Lets create a simple Gaussian topo # and set the active cells [xx, yy] = np.meshgrid( np.linspace(-200, 200, 50), np.linspace(-200, 200, 50) ) b = 100 A = 50 zz = A*np.exp(-0.5*((xx/b)**2. + (yy/b)**2.)) # We would usually load a topofile topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)] # Create and array of observation points xr = np.linspace(-100., 100., 20) yr = np.linspace(-100., 100., 20) X, Y = np.meshgrid(xr, yr) Z = A*np.exp(-0.5*((X/b)**2. + (Y/b)**2.)) + 5 # Create a MAGsurvey xyzLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)] rxLoc = PF.BaseMag.RxObs(xyzLoc) srcField = PF.BaseMag.SrcField([rxLoc], param=H0) survey = PF.BaseMag.LinearSurvey(srcField) # Create a mesh h = [5, 5, 5] padDist = np.ones((3, 2)) * 100 nCpad = [2, 4, 2] # Get extent of points limx = np.r_[topo[:, 0].max(), topo[:, 0].min()] limy = np.r_[topo[:, 1].max(), topo[:, 1].min()] limz = np.r_[topo[:, 2].max(), topo[:, 2].min()] # Get center of the mesh midX = np.mean(limx) midY = np.mean(limy) midZ = np.mean(limz) nCx = int(limx[0]-limx[1]) / h[0] nCy = int(limy[0]-limy[1]) / h[1] nCz = int(limz[0]-limz[1]+int(np.min(np.r_[nCx, nCy])/3)) / h[2] # Figure out full extent required from input extent = np.max(np.r_[nCx * h[0] + padDist[0, :].sum(), nCy * h[1] + padDist[1, :].sum(), nCz * h[2] + padDist[2, :].sum()]) maxLevel = int(np.log2(extent/h[0]))+1 # Number of cells at the small octree level nCx, nCy, nCz = 2**(maxLevel), 2**(maxLevel), 2**(maxLevel) # Define the mesh and origin # For now cubic cells mesh = Mesh.TreeMesh([np.ones(nCx)*h[0], np.ones(nCx)*h[1], np.ones(nCx)*h[2]]) # Set origin mesh.x0 = np.r_[ -nCx*h[0]/2.+midX, -nCy*h[1]/2.+midY, -nCz*h[2]/2.+midZ ] # Refine the mesh around topography # Get extent of points F = NearestNDInterpolator(topo[:, :2], topo[:, 2]) zOffset = 0 # Cycle through the first 3 octree levels for ii in range(3): dx = mesh.hx.min()*2**ii nCx = int((limx[0]-limx[1]) / dx) nCy = int((limy[0]-limy[1]) / dx) # Create a grid at the octree level in xy CCx, CCy = np.meshgrid( np.linspace(limx[1], limx[0], nCx), np.linspace(limy[1], limy[0], nCy) ) z = F(mkvc(CCx), mkvc(CCy)) # level means number of layers in current OcTree level for level in range(int(nCpad[ii])): mesh.insert_cells( np.c_[ mkvc(CCx), mkvc(CCy), z-zOffset ], np.ones_like(z)*maxLevel-ii, finalize=False ) zOffset += dx mesh.finalize() self.mesh = mesh # Define an active cells from topo actv = Utils.surface2ind_topo(mesh, topo) nC = int(actv.sum()) model = np.zeros((mesh.nC, 3)) # Convert the inclination declination to vector in Cartesian M_xyz = Utils.matutils.dip_azimuth2cartesian(M[0], M[1]) # Get the indicies of the magnetized block ind = Utils.ModelBuilder.getIndicesBlock( np.r_[-20, -20, -10], np.r_[20, 20, 25], mesh.gridCC, )[0] # Assign magnetization values model[ind, :] = np.kron( np.ones((ind.shape[0], 1)), M_xyz*0.05 ) # Remove air cells self.model = model[actv, :] # Create active map to go from reduce set to full self.actvMap = Maps.InjectActiveCells(mesh, actv, np.nan) # Creat reduced identity map idenMap = Maps.IdentityMap(nP=nC*3) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral( mesh, chiMap=idenMap, actInd=actv, modelType='vector' ) # Pair the survey and problem survey.pair(prob) # Compute some data and add some random noise data = prob.fields(Utils.mkvc(self.model)) std = 5 # nT data += np.random.randn(len(data))*std wd = np.ones(len(data))*std # Assigne data and uncertainties to the survey survey.dobs = data survey.std = wd # Create an projection matrix for plotting later actvPlot = Maps.InjectActiveCells(mesh, actv, np.nan) # Create sensitivity weights from our linear forward operator rxLoc = survey.srcField.rxList[0].locs # This Mapping connects the regularizations for the three-component # vector model wires = Maps.Wires(('p', nC), ('s', nC), ('t', nC)) # Create sensitivity weights from our linear forward operator # so that all cells get equal chance to contribute to the solution wr = np.sum(prob.G**2., axis=0)**0.5 wr = (wr/np.max(wr)) # Create three regularization for the different components # of magnetization reg_p = Regularization.Sparse(mesh, indActive=actv, mapping=wires.p) reg_p.mref = np.zeros(3*nC) reg_p.cell_weights = (wires.p * wr) reg_s = Regularization.Sparse(mesh, indActive=actv, mapping=wires.s) reg_s.mref = np.zeros(3*nC) reg_s.cell_weights = (wires.s * wr) reg_t = Regularization.Sparse(mesh, indActive=actv, mapping=wires.t) reg_t.mref = np.zeros(3*nC) reg_t.cell_weights = (wires.t * wr) reg = reg_p + reg_s + reg_t reg.mref = np.zeros(3*nC) # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1./survey.std # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=30, lower=-10, upper=10., maxIterLS=20, maxIterCG=20, tolCG=1e-4) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) # A list of directive to control the inverson betaest = Directives.BetaEstimate_ByEig() # Here is where the norms are applied # Use pick a treshold parameter empirically based on the distribution of # model parameters IRLS = Directives.Update_IRLS( f_min_change=1e-3, maxIRLSiter=0, beta_tol=5e-1 ) # Pre-conditioner update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi, betaest]) # Run the inversion m0 = np.ones(3*nC) * 1e-4 # Starting model mrec_MVIC = inv.run(m0) self.mstart = Utils.matutils.cartesian2spherical(mrec_MVIC.reshape((nC, 3), order='F')) beta = invProb.beta dmis.prob.coordinate_system = 'spherical' dmis.prob.model = self.mstart # Create a block diagonal regularization wires = Maps.Wires(('amp', nC), ('theta', nC), ('phi', nC)) # Create a Combo Regularization # Regularize the amplitude of the vectors reg_a = Regularization.Sparse(mesh, indActive=actv, mapping=wires.amp) reg_a.norms = np.c_[0., 0., 0., 0.] # Sparse on the model and its gradients reg_a.mref = np.zeros(3*nC) # Regularize the vertical angle of the vectors reg_t = Regularization.Sparse(mesh, indActive=actv, mapping=wires.theta) reg_t.alpha_s = 0. # No reference angle reg_t.space = 'spherical' reg_t.norms = np.c_[2., 0., 0., 0.] # Only norm on gradients used # Regularize the horizontal angle of the vectors reg_p = Regularization.Sparse(mesh, indActive=actv, mapping=wires.phi) reg_p.alpha_s = 0. # No reference angle reg_p.space = 'spherical' reg_p.norms = np.c_[2., 0., 0., 0.] # Only norm on gradients used reg = reg_a + reg_t + reg_p reg.mref = np.zeros(3*nC) Lbound = np.kron(np.asarray([0, -np.inf, -np.inf]), np.ones(nC)) Ubound = np.kron(np.asarray([10, np.inf, np.inf]), np.ones(nC)) # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=20, lower=Lbound, upper=Ubound, maxIterLS=20, maxIterCG=30, tolCG=1e-3, stepOffBoundsFact=1e-3, ) opt.approxHinv = None invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=beta*10.) # Here is where the norms are applied IRLS = Directives.Update_IRLS(f_min_change=1e-4, maxIRLSiter=20, minGNiter=1, beta_tol=0.5, coolingRate=1, coolEps_q=True, betaSearch=False) # Special directive specific to the mag amplitude problem. The sensitivity # weights are update between each iteration. ProjSpherical = Directives.ProjectSphericalBounds() update_SensWeight = Directives.UpdateSensitivityWeights() update_Jacobi = Directives.UpdatePreconditioner() self.inv = Inversion.BaseInversion( invProb, directiveList=[ ProjSpherical, IRLS, update_SensWeight, update_Jacobi ] )