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 setUp(self): cs = 25. hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hz = [(cs, 0, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hz], x0="CN") blkind0 = Utils.ModelBuilder.getIndicesSphere(np.r_[-100., -200.], 75., mesh.gridCC) blkind1 = Utils.ModelBuilder.getIndicesSphere(np.r_[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.1 x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] Aloc = np.r_[-200., 0.] Bloc = np.r_[200., 0.] M = Utils.ndgrid(x - 25., np.r_[0.]) N = Utils.ndgrid(x + 25., 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.Problem2D_CC(mesh, rho=1. / sigma, etaMap=wires.eta, tauiMap=wires.taui, verbose=False) 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
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.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]) wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC)) problem = SIP.Problem3D_N( mesh, sigma=sigma, etaMap=wires.eta, tauiMap=wires.taui ) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta, 1./tau] 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): mesh = Mesh.TensorMesh([30, 30], x0=[-0.5, -1.]) sigma = np.ones(mesh.nC) model = np.log(sigma) prob = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) rx = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.max()]]) ) src = DC.Src.Dipole( [rx], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()] ) survey = DC.Survey([src]) prob.pair(survey) self.std = 0.01 survey.std = self.std dobs = survey.makeSyntheticData(model) self.eps = 1e-8 * np.min(np.abs(dobs)) survey.eps = self.eps dmis = DataMisfit.l2_DataMisfit(survey) self.model = model self.mesh = mesh self.survey = survey self.prob = prob self.dobs = dobs self.dmis = dmis
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(delt=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=times, fieldType='dbdt', fieldComp='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) Survey.t_active = np.zeros(Survey.nD, dtype=bool) Survey.set_active_interval(-1e6, 1e6) Problem = VRM.Problem_Linear(meshObj, ref_factor=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 setUp(self): mesh = Mesh.TensorMesh([30, 30], x0=[-0.5, -1.]) sigma = np.ones(mesh.nC) model = np.log(sigma) prob = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) rx = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.max()]]) ) src = DC.Src.Dipole( [rx], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()] ) survey = DC.Survey([src]) prob.pair(survey) dobs = survey.makeSyntheticData(model) dmis = DataMisfit.l2_DataMisfit(survey) self.model = model self.mesh = mesh self.survey = survey self.prob = prob self.dobs = dobs self.dmis = dmis
def setUp(self, parallel=False): frequency = np.array([900, 7200, 56000], dtype=float) hz = np.r_[1.] n_sounding = 10 dx = 20. hx = np.ones(n_sounding) * dx e = np.ones(n_sounding) mSynth = np.r_[e * np.log(1. / 100.), e * 20] x = np.arange(n_sounding) y = np.zeros_like(x) z = np.ones_like(x) * 30. rx_locations = np.c_[x, y, z] src_locations = np.c_[x, y, z] topo = np.c_[x, y, z - 30.].astype(float) wires = Maps.Wires(('sigma', n_sounding), ('h', n_sounding)) expmap = Maps.ExpMap(nP=n_sounding) sigmaMap = expmap * wires.sigma survey = GlobalEM1DSurveyFD(rx_locations=rx_locations, src_locations=src_locations, frequency=frequency, offset=np.ones_like(frequency) * 8., src_type="VMD", rx_type="ppm", field_type='secondary', topo=topo, half_switch=True) problem = GlobalEM1DProblemFD([], sigmaMap=sigmaMap, hMap=wires.h, hz=hz, parallel=parallel, n_cpu=2) problem.pair(survey) survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization mesh = Mesh.TensorMesh([int(n_sounding * 2)]) 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 = problem self.mesh = mesh self.m0 = mSynth * 1.2 self.survey = survey self.dmis = dmis
def run(N=100, plotIt=True): np.random.seed(1) mesh = Mesh.TensorMesh([N]) nk = 20 jk = np.linspace(1., 60., nk) p = -0.25 q = 0.25 def g(k): return ( np.exp(p*jk[k]*mesh.vectorCCx) * np.cos(np.pi*q*jk[k]*mesh.vectorCCx) ) G = np.empty((nk, mesh.nC)) for i in range(nk): G[i, :] = g(i) mtrue = np.zeros(mesh.nC) mtrue[mesh.vectorCCx > 0.3] = 1. mtrue[mesh.vectorCCx > 0.45] = -0.5 mtrue[mesh.vectorCCx > 0.6] = 0 prob = Problem.LinearProblem(mesh, G=G) survey = Survey.LinearSurvey() survey.pair(prob) survey.makeSyntheticData(mtrue, std=0.01) M = prob.mesh reg = Regularization.Tikhonov(mesh, alpha_s=1., alpha_x=1.) dmis = DataMisfit.l2_DataMisfit(survey) opt = Optimization.InexactGaussNewton(maxIter=60) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) directives = [ Directives.BetaEstimate_ByEig(beta0_ratio=1e-2), Directives.TargetMisfit() ] inv = Inversion.BaseInversion(invProb, directiveList=directives) m0 = np.zeros_like(survey.mtrue) mrec = inv.run(m0) if plotIt: fig, axes = plt.subplots(1, 2, figsize=(12*1.2, 4*1.2)) for i in range(prob.G.shape[0]): axes[0].plot(prob.G[i, :]) axes[0].set_title('Columns of matrix G') axes[1].plot(M.vectorCCx, survey.mtrue, 'b-') axes[1].plot(M.vectorCCx, mrec, 'r-') axes[1].legend(('True Model', 'Recovered Model')) axes[1].set_ylim([-2, 2]) return prob, survey, mesh, mrec
def setUp(self, parallel=True): frequency = np.array([900, 7200, 56000], dtype=float) hz = get_vertical_discretization_frequency( frequency, sigma_background=1./10. ) n_sounding = 10 dx = 20. hx = np.ones(n_sounding) * dx mesh = Mesh.TensorMesh([hx, hz], x0='00') inds = mesh.gridCC[:, 1] < 25 inds_1 = mesh.gridCC[:, 1] < 50 sigma = np.ones(mesh.nC) * 1./100. sigma[inds_1] = 1./10. sigma[inds] = 1./50. sigma_em1d = sigma.reshape(mesh.vnC, order='F').flatten() mSynth = np.log(sigma_em1d) x = mesh.vectorCCx y = np.zeros_like(x) z = np.ones_like(x) * 30. rx_locations = np.c_[x, y, z] src_locations = np.c_[x, y, z] topo = np.c_[x, y, z-30.].astype(float) mapping = Maps.ExpMap(mesh) survey = GlobalEM1DSurveyFD( rx_locations=rx_locations, src_locations=src_locations, frequency=frequency, offset=np.ones_like(frequency) * 8., src_type="VMD", rx_type="Hz", field_type='secondary', topo=topo ) problem = GlobalEM1DProblemFD( [], sigmaMap=mapping, hz=hz, parallel=parallel, n_cpu=5 ) problem.pair(survey) 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=0.) 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, parallel=True): frequency = np.array([900, 7200, 56000], dtype=float) hz = get_vertical_discretization_frequency( frequency, sigma_background=1./10. ) n_sounding = 10 dx = 20. hx = np.ones(n_sounding) * dx mesh = Mesh.TensorMesh([hx, hz], x0='00') inds = mesh.gridCC[:, 1] < 25 inds_1 = mesh.gridCC[:, 1] < 50 sigma = np.ones(mesh.nC) * 1./100. sigma[inds_1] = 1./10. sigma[inds] = 1./50. sigma_em1d = sigma.reshape(mesh.vnC, order='F').flatten() mSynth = np.log(sigma_em1d) x = mesh.vectorCCx y = np.zeros_like(x) z = np.ones_like(x) * 30. rx_locations = np.c_[x, y, z] src_locations = np.c_[x, y, z] topo = np.c_[x, y, z-30.].astype(float) mapping = Maps.ExpMap(mesh) survey = GlobalEM1DSurveyFD( rx_locations=rx_locations, src_locations=src_locations, frequency=frequency, offset=np.ones_like(frequency) * 8., src_type="VMD", rx_type="Hz", field_type='secondary', topo=topo ) problem = GlobalEM1DProblemFD( [], sigmaMap=mapping, hz=hz, parallel=parallel, n_cpu=2 ) problem.pair(survey) 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=0.) 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, parallel=True): frequency = np.array([900, 7200, 56000], dtype=float) hz = np.r_[1.] n_sounding = 10 dx = 20. hx = np.ones(n_sounding) * dx e = np.ones(n_sounding) mSynth = np.r_[e*np.log(1./100.), e*20] x = np.arange(n_sounding) y = np.zeros_like(x) z = np.ones_like(x) * 30. rx_locations = np.c_[x, y, z] src_locations = np.c_[x, y, z] topo = np.c_[x, y, z-30.].astype(float) wires = Maps.Wires(('sigma', n_sounding),('h', n_sounding)) expmap = Maps.ExpMap(nP=n_sounding) sigmaMap = expmap * wires.sigma survey = GlobalEM1DSurveyFD( rx_locations=rx_locations, src_locations=src_locations, frequency=frequency, offset=np.ones_like(frequency) * 8., src_type="VMD", rx_type="ppm", field_type='secondary', topo=topo, half_switch=True ) problem = GlobalEM1DProblemFD( [], sigmaMap=sigmaMap, hMap=wires.h, hz=hz, parallel=parallel, n_cpu=2 ) problem.pair(survey) survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization mesh = Mesh.TensorMesh([int(n_sounding * 2)]) 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 = problem self.mesh = mesh self.m0 = mSynth * 1.2 self.survey = survey self.dmis = dmis
def run(N=100, plotIt=True): np.random.seed(1) mesh = Mesh.TensorMesh([N]) nk = 20 jk = np.linspace(1., 60., nk) p = -0.25 q = 0.25 def g(k): return (np.exp(p * jk[k] * mesh.vectorCCx) * np.cos(np.pi * q * jk[k] * mesh.vectorCCx)) G = np.empty((nk, mesh.nC)) for i in range(nk): G[i, :] = g(i) mtrue = np.zeros(mesh.nC) mtrue[mesh.vectorCCx > 0.3] = 1. mtrue[mesh.vectorCCx > 0.45] = -0.5 mtrue[mesh.vectorCCx > 0.6] = 0 prob = Problem.LinearProblem(mesh, G=G) survey = Survey.LinearSurvey() survey.pair(prob) survey.makeSyntheticData(mtrue, std=0.01) M = prob.mesh reg = Regularization.Tikhonov(mesh, alpha_s=1., alpha_x=1.) dmis = DataMisfit.l2_DataMisfit(survey) opt = Optimization.InexactGaussNewton(maxIter=60) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) directives = [ Directives.BetaEstimate_ByEig(beta0_ratio=1e-2), Directives.TargetMisfit() ] inv = Inversion.BaseInversion(invProb, directiveList=directives) m0 = np.zeros_like(survey.mtrue) mrec = inv.run(m0) if plotIt: fig, axes = plt.subplots(1, 2, figsize=(12 * 1.2, 4 * 1.2)) for i in range(prob.G.shape[0]): axes[0].plot(prob.G[i, :]) axes[0].set_title('Columns of matrix G') axes[1].plot(M.vectorCCx, survey.mtrue, 'b-') axes[1].plot(M.vectorCCx, mrec, 'r-') axes[1].legend(('True Model', 'Recovered Model')) axes[1].set_ylim([-2, 2]) return prob, survey, mesh, mrec
def setUp(self): mesh = Mesh.TensorMesh([30, 30], x0=[-0.5, -1.]) sigma = np.random.rand(mesh.nC) model = np.log(sigma) prob = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) prob1 = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) rx = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.max()]]) ) rx1 = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.min()]]) ) src = DC.Src.Dipole( [rx], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()] ) src1 = DC.Src.Dipole( [rx1], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()] ) survey = DC.Survey([src]) prob.pair(survey) survey1 = DC.Survey([src1]) prob1.pair(survey1) dobs0 = survey.makeSyntheticData(model) dobs1 = survey1.makeSyntheticData(model) self.mesh = mesh self.model = model self.survey0 = survey self.prob0 = prob self.survey1 = survey1 self.prob1 = prob1 self.dmis0 = DataMisfit.l2_DataMisfit(self.survey0) self.dmis1 = DataMisfit.l2_DataMisfit(self.survey1) self.dmiscobmo = self.dmis0 + self.dmis1
def fit_colecole_with_se(self, eta_cc=0.8, tau_cc=0.003, c_cc=0.6): def ColeColeSeigel(f, sigmaInf, eta, tau, c): w = 2 * np.pi * f return sigmaInf * (1 - eta / (1 + (1j * w * tau)**c)) # Step1: Fit Cole-Cole with Stretched Exponential function time = np.logspace(-6, np.log10(0.01), 41) wt, tbase, omega_int = DigFilter.setFrequency(time) frequency = omega_int / (2 * np.pi) # Cole-Cole parameters siginf = 1. self.eta_cc = eta_cc self.tau_cc = tau_cc self.c_cc = c_cc sigma = ColeColeSeigel(frequency, siginf, eta_cc, tau_cc, c_cc) sigTCole = DigFilter.transFiltImpulse(sigma, wt, tbase, omega_int, time, tol=1e-12) wires = Maps.Wires(('eta', 1), ('tau', 1), ('c', 1)) taumap = Maps.ExpMap(nP=1) * wires.tau survey = SESurvey() dtrue = -sigTCole survey.dobs = dtrue m1D = Mesh.TensorMesh([np.ones(3)]) prob = SEInvImpulseProblem(m1D, etaMap=wires.eta, tauMap=taumap, cMap=wires.c) update_sens = Directives.UpdateSensitivityWeights() prob.time = time prob.pair(survey) m0 = np.r_[eta_cc, np.log(tau_cc), c_cc] perc = 0.05 dmisfitpeta = DataMisfit.l2_DataMisfit(survey) dmisfitpeta.W = 1 / (abs(survey.dobs) * perc) reg = regularization.Simple(m1D) opt = Optimization.ProjectedGNCG(maxIter=10) invProb = InvProblem.BaseInvProblem(dmisfitpeta, reg, opt) # Create an inversion object target = Directives.TargetMisfit() invProb.beta = 0. inv = Inversion.BaseInversion(invProb, directiveList=[target]) reg.mref = 0. * m0 prob.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') opt.tolX = 1e-20 opt.tolF = 1e-20 opt.tolG = 1e-20 opt.eps = 1e-20 mopt = inv.run(m0) return mopt
def makeSubProblem(args): globalMesh, globalActive, globalSurvey, globalTree, ind, h, padDist = args rxLoc = globalSurvey.srcField.rxList[0].locs loc = np.c_[rxLoc[ind, :]].T rx = PF.BaseMag.RxObs(loc) srcField = PF.BaseMag.SrcField([rx], param=globalSurvey.srcField.param) survey_t = PF.BaseMag.LinearSurvey(srcField) survey_t.dobs = np.c_[globalSurvey.dobs[ind]] survey_t.std = np.c_[globalSurvey.std[ind]] survey_t.index = ind # Create a mesh # Keep same fine cells as global h = [globalMesh.hx.min(), globalMesh.hy.min(), globalMesh.hz.min()] mesh_t = Utils.modelutils.meshBuilder(rxLoc, h, padDist, meshType='TREE', meshGlobal=globalMesh, verticalAlignment='center') # Refine the mesh around loc mesh_t = Utils.modelutils.refineTree(mesh_t, loc, dtype='point', nCpad=[3, 3, 3], finalize=True) actv_t = np.ones(mesh_t.nC, dtype='bool') # Create reduced identity map tileMap = Maps.Tile((globalMesh, globalActive), (mesh_t, actv_t)) tileMap._tree = globalTree # Create the forward model operator prob_t = PF.Magnetics.MagneticIntegral(mesh_t, chiMap=tileMap, actInd=actv_t, verbose=False) survey_t.pair(prob_t) # Pre-calc sensitivities and projections prob_t.G tileMap.P # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey_t, eps=survey_t.std) dmis.W = 1. / survey_t.std return dmis
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
def setUp(self): mesh = Mesh.TensorMesh([20, 20, 20], "CCN") sigma = np.ones(mesh.nC) * 1. / 100. actind = mesh.gridCC[:, 2] < -0.2 # actMap = Maps.InjectActiveCells(mesh, actind, 0.) xyzM = Utils.ndgrid( np.ones_like(mesh.vectorCCx[:-1]) * -0.4, np.ones_like(mesh.vectorCCy) * -0.4, np.r_[-0.3]) xyzN = Utils.ndgrid(mesh.vectorCCx[1:], mesh.vectorCCy, np.r_[-0.3]) problem = SP.Problem_CC(mesh, sigma=sigma, qMap=Maps.IdentityMap(mesh), Solver=PardisoSolver) rx = SP.Rx.Dipole(xyzN, xyzM) src = SP.Src.StreamingCurrents([rx], L=np.ones(mesh.nC), mesh=mesh, modelType="CurrentSource") survey = SP.Survey([src]) survey.pair(problem) q = np.zeros(mesh.nC) inda = Utils.closestPoints(mesh, np.r_[-0.5, 0., -0.8]) indb = Utils.closestPoints(mesh, np.r_[0.5, 0., -0.8]) q[inda] = 1. q[indb] = -1. mSynth = q.copy() survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Simple(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=1e-2) 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): mesh = Mesh.TensorMesh([30, 30], x0=[-0.5, -1.]) sigma = np.random.rand(mesh.nC) model = np.log(sigma) prob = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) prob1 = DC.Problem3D_CC(mesh, rhoMap=Maps.ExpMap(mesh)) rx = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.max()]])) rx1 = DC.Rx.Pole( Utils.ndgrid([mesh.vectorCCx, np.r_[mesh.vectorCCy.min()]])) src = DC.Src.Dipole([rx], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()]) src1 = DC.Src.Dipole([rx1], np.r_[-0.25, mesh.vectorCCy.max()], np.r_[0.25, mesh.vectorCCy.max()]) survey = DC.Survey([src]) prob.pair(survey) survey1 = DC.Survey([src1]) prob1.pair(survey1) dobs0 = survey.makeSyntheticData(model) dobs1 = survey1.makeSyntheticData(model) self.mesh = mesh self.model = model self.survey0 = survey self.prob0 = prob self.survey1 = survey1 self.prob1 = prob1 self.dmis0 = DataMisfit.l2_DataMisfit(self.survey0) self.dmis1 = DataMisfit.l2_DataMisfit(self.survey1) self.dmiscobmo = self.dmis0 + self.dmis1
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(-200, 200., 20) x = np.linspace(-200, 200., 2) 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.] B0loc = np.r_[-130, 0.] B1loc = np.r_[-110, 0.] rx = DC.Rx.Dipole_ky(M, N) src0 = DC.Src.Dipole([rx], A0loc, B0loc) src1 = DC.Src.Dipole([rx], A1loc, B1loc) survey = IP.Survey([src0, src1]) sigma = np.ones(mesh.nC) * 1. problem = IP.Problem2D_CC(mesh, sigma=sigma, etaMap=Maps.IdentityMap(mesh), verbose=False) problem.pair(survey) mSynth = np.ones(mesh.nC) * 0.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=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 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)
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(-200, 200., 20) x = np.linspace(-200, 200., 2) 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.] B0loc = np.r_[-130, 0.] B1loc = np.r_[-110, 0.] rx = DC.Rx.Dipole_ky(M, N) src0 = DC.Src.Dipole([rx], A0loc, B0loc) src1 = DC.Src.Dipole([rx], A1loc, B1loc) survey = IP.Survey([src0, src1]) sigma = np.ones(mesh.nC) * 1. problem = IP.Problem2D_CC( mesh, sigma=sigma, etaMap=Maps.IdentityMap(mesh), verbose=False ) problem.pair(survey) mSynth = np.ones(mesh.nC)*0.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=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 run_inversion_direct( self, m0=0.0, mref=0.0, percentage=5, floor=0.1, chi_fact=1.0, beta_min=1e-4, beta_max=1e0, n_beta=31, alpha_s=1.0, alpha_x=1.0, ): 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 betas = np.logspace(np.log10(beta_min), np.log10(beta_max), n_beta)[::-1] phi_d = np.zeros(n_beta, dtype=float) phi_m = np.zeros(n_beta, dtype=float) models = [] preds = [] G = dmis.W.dot(self.G) for ii, beta in enumerate(betas): A = G.T.dot(G) + beta * reg.deriv2(m0) b = -(dmis.deriv(m0) + beta * reg.deriv(m0)) m = np.linalg.solve(A, b) phi_d[ii] = dmis(m) * 2.0 phi_m[ii] = reg(m) * 2.0 models.append(m) preds.append(survey.dpred(m)) return phi_d, phi_m, models, preds, betas
def setUp(self): mesh = Mesh.TensorMesh([4, 4, 4]) # Magnetic inducing field parameter (A,I,D) B = [50000, 90, 0] # Create a MAGsurvey rx = PF.BaseMag.RxObs( np.vstack([[0.25, 0.25, 0.25], [-0.25, -0.25, 0.25]]) ) srcField = PF.BaseMag.SrcField([rx], param=(B[0], B[1], B[2])) survey = PF.BaseMag.LinearSurvey(srcField) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral( mesh, chiMap=Maps.IdentityMap(mesh) ) # Pair the survey and problem survey.pair(prob) # Compute forward model some data m = np.random.rand(mesh.nC) survey.makeSyntheticData(m) reg = Regularization.Sparse(mesh) reg.mref = np.zeros(mesh.nC) wr = np.sum(prob.G**2., axis=0)**0.5 reg.cell_weights = wr reg.norms = [0, 1, 1, 1] reg.eps_p, reg.eps_q = 1e-3, 1e-3 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1./survey.std # Add directives to the inversion opt = Optimization.ProjectedGNCG( maxIter=2, lower=-10., upper=10., maxIterCG=2 ) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) self.mesh = mesh self.invProb = invProb
def setUp(self): mesh = Mesh.TensorMesh([4, 4, 4]) # Magnetic inducing field parameter (A,I,D) B = [50000, 90, 0] # Create a MAGsurvey rx = PF.BaseMag.RxObs( np.vstack([[0.25, 0.25, 0.25], [-0.25, -0.25, 0.25]])) srcField = PF.BaseMag.SrcField([rx], param=(B[0], B[1], B[2])) survey = PF.BaseMag.LinearSurvey(srcField) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=Maps.IdentityMap(mesh)) # Pair the survey and problem survey.pair(prob) # Compute forward model some data m = np.random.rand(mesh.nC) survey.makeSyntheticData(m) reg = Regularization.Sparse(mesh) reg.mref = np.zeros(mesh.nC) wr = np.sum(prob.G**2., axis=0)**0.5 reg.cell_weights = wr reg.norms = [0, 1, 1, 1] reg.eps_p, reg.eps_q = 1e-3, 1e-3 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / survey.std # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=2, lower=-10., upper=10., maxIterCG=2) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) self.mesh = mesh self.invProb = invProb
def setUp(self): aSpacing = 2.5 nElecs = 10 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_N(mesh, rhoMap=Maps.IdentityMap(mesh), storeJ=True) 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): mesh = Mesh.TensorMesh([20, 20, 20], "CCN") sigma = np.ones(mesh.nC)*1./100. actind = mesh.gridCC[:, 2] < -0.2 # actMap = Maps.InjectActiveCells(mesh, actind, 0.) xyzM = Utils.ndgrid(np.ones_like(mesh.vectorCCx[:-1])*-0.4, np.ones_like(mesh.vectorCCy)*-0.4, np.r_[-0.3]) xyzN = Utils.ndgrid(mesh.vectorCCx[1:], mesh.vectorCCy, np.r_[-0.3]) problem = SP.Problem_CC(mesh, sigma=sigma, qMap=Maps.IdentityMap(mesh), Solver=PardisoSolver) rx = SP.Rx.Dipole(xyzN, xyzM) src = SP.Src.StreamingCurrents([rx], L=np.ones(mesh.nC), mesh=mesh, modelType="CurrentSource") survey = SP.Survey([src]) survey.pair(problem) q = np.zeros(mesh.nC) inda = Utils.closestPoints(mesh, np.r_[-0.5, 0., -0.8]) indb = Utils.closestPoints(mesh, np.r_[0.5, 0., -0.8]) q[inda] = 1. q[indb] = -1. mSynth = q.copy() survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Simple(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=1e-2) 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 setUp(self): cs = 12.5 hx = [(cs, 2, -1.3), (cs, 61), (cs, 2, 1.3)] hy = [(cs, 2, -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, rhoMap=Maps.IdentityMap(mesh), Solver=Solver ) 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 setUp(self): aSpacing = 2.5 nElecs = 10 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_N( mesh, rhoMap=Maps.IdentityMap(mesh), storeJ=True ) 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 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
cb = plt.colorbar(dat[0], ax=ax[0]) ax[0].set_title("Vertical section") cb.set_label("Conductivity (S/m)") ax[0].set_xlabel('Easting (m)') ax[0].set_ylabel('Depth (m)') ax[0].set_xlim(-1000., 1000.) ax[0].set_ylim(-500., 0.) ############################################################################### # Step 6 # ------ # # Run inversion regmesh = Mesh.TensorMesh([31]) dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(regmesh) opt = Optimization.InexactGaussNewton(maxIter=7, tolX=1e-15) opt.remember('xc') invProb = InvProblem.BaseInvProblem(dmis, reg, opt) beta = Directives.BetaEstimate_ByEig(beta0_ratio=1e1) betaSched = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaSched]) # Choose an initial starting model of the background conductivity m0 = np.log(np.ones(mapping.nP)*sighalf) mopt = inv.run(m0) ############################################################################### # Step 7
def createLocalProb(rxLoc, wrGlobal, lims): # Grab the data for current tile ind_t = np.all([ rxLoc[:, 0] >= lims[0], rxLoc[:, 0] <= lims[1], rxLoc[:, 1] >= lims[2], rxLoc[:, 1] <= lims[3], surveyMask ], axis=0) # Remember selected data in case of tile overlap surveyMask[ind_t] = False # Create new survey rxLoc_t = PF.BaseGrav.RxObs(rxLoc[ind_t, :]) srcField = PF.BaseGrav.SrcField([rxLoc_t]) survey_t = PF.BaseGrav.LinearSurvey(srcField) survey_t.dobs = survey.dobs[ind_t] survey_t.std = survey.std[ind_t] survey_t.ind = ind_t # mesh_t = meshTree.copy() mesh_t = Utils.modelutils.meshBuilder(rxLoc[ind_t, :], h, padDist, meshGlobal=meshInput, meshType='TREE', gridLoc='CC') mesh_t = Utils.modelutils.refineTree(mesh_t, topo, dtype='surface', nCpad=[0, 3, 2], finalize=False) mesh_t = Utils.modelutils.refineTree(mesh_t, rxLoc[ind_t, :], dtype='surface', nCpad=[10, 5, 5], finalize=False) center = np.mean(rxLoc[ind_t, :], axis=0) tileCenter = np.r_[np.mean(lims[0:2]), np.mean(lims[2:]), center[2]] ind = closestPoints(mesh, tileCenter, gridLoc='CC') shift = np.squeeze(mesh.gridCC[ind, :]) - center mesh_t.x0 += shift mesh_t.finalize() print(mesh_t.nC) actv_t = Utils.surface2ind_topo(mesh_t, topo) # Create reduced identity map tileMap = Maps.Tile((mesh, actv), (mesh_t, actv_t)) tileMap.nCell = 40 tileMap.nBlock = 1 # Create the forward model operator prob = PF.Gravity.GravityIntegral(mesh_t, rhoMap=tileMap, actInd=actv_t, memory_saving_mode=True, parallelized=True) survey_t.pair(prob) # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey_t) dmis.W = 1. / survey_t.std wrGlobal += prob.getJtJdiag(np.ones(tileMap.P.shape[1])) # Create combo misfit function return dmis, wrGlobal
def createLocalProb(meshLocal, local_survey, global_weights, ind): """ CreateLocalProb(rxLoc, global_weights, lims, ind) Generate a problem, calculate/store sensitivities for given data points """ # Need to find a way to compute sensitivities only for intersecting cells activeCells_t = np.ones(meshLocal.nC, dtype='bool') # Create reduced identity map if input_dict["inversion_type"] in ['mvi', 'mvis']: nBlock = 3 else: nBlock = 1 tile_map = Maps.Tile( (mesh, activeCells), (meshLocal, activeCells_t), nBlock=nBlock ) activeCells_t = tile_map.activeLocal if "adjust_clearance" in list(input_dict.keys()): print("Setting Z values of data to respect clearance height") _, c_ind = tree.query(local_survey.rxLoc) dz = input_dict["adjust_clearance"] z = ( mesh.gridCC[activeCells, 2][c_ind] + mesh.h_gridded[activeCells, 2][c_ind]/2 + dz ) local_survey.srcField.rxList[0].locs[:, 2] = z if input_dict["inversion_type"] == 'grav': prob = PF.Gravity.GravityIntegral( meshLocal, rhoMap=tile_map*model_map, actInd=activeCells_t, parallelized=parallelized, Jpath=outDir + "Tile" + str(ind) + ".zarr", maxRAM=max_ram, n_cpu=n_cpu, max_chunk_size=max_chunk_size, chunk_by_rows=chunk_by_rows ) elif input_dict["inversion_type"] == 'mag': prob = PF.Magnetics.MagneticIntegral( meshLocal, chiMap=tile_map*model_map, actInd=activeCells_t, parallelized=parallelized, Jpath=outDir + "Tile" + str(ind) + ".zarr", maxRAM=max_ram, n_cpu=n_cpu, max_chunk_size=max_chunk_size, chunk_by_rows=chunk_by_rows ) elif input_dict["inversion_type"] in ['mvi', 'mvis']: prob = PF.Magnetics.MagneticIntegral( meshLocal, chiMap=tile_map*model_map, actInd=activeCells_t, parallelized=parallelized, Jpath=outDir + "Tile" + str(ind) + ".zarr", maxRAM=max_ram, modelType='vector', n_cpu=n_cpu, max_chunk_size=max_chunk_size, chunk_by_rows=chunk_by_rows ) local_survey.pair(prob) # Data misfit function local_misfit = DataMisfit.l2_DataMisfit(local_survey) local_misfit.W = 1./local_survey.std wr = prob.getJtJdiag(np.ones_like(mstart), W=local_misfit.W) activeCellsTemp = Maps.InjectActiveCells(mesh, activeCells, 1e-8) global_weights += wr del meshLocal if output_tile_files: if input_dict["inversion_type"] == 'grav': Utils.io_utils.writeUBCgravityObservations( outDir + 'Survey_Tile' + str(ind) + '.dat', local_survey, local_survey.dobs ) elif input_dict["inversion_type"] == 'mag': Utils.io_utils.writeUBCmagneticsObservations( outDir + 'Survey_Tile' + str(ind) + '.dat', local_survey, local_survey.dobs ) Mesh.TreeMesh.writeUBC( mesh, outDir + 'Octree_Tile' + str(ind) + '.msh', models={outDir + 'JtJ_Tile' + str(ind) + ' .act': activeCellsTemp*wr[:nC]} ) return local_misfit, global_weights
srclist.append(src) #print "line2",locA,locB,"\n",[M,N],"\n" #rx = DC.Rx.Dipole(-M,-N) #src= DC.Src.Dipole([rx],-locA,-locB) #srclist.append(src) mapping = Maps.ExpMap(mesh) survey = DC.Survey(srclist) problem = DC.Problem3D_CC(mesh, sigmaMap=mapping) problem.pair(survey) problem.Solver = PardisoSolver survey.dobs = survey.dpred(mtrue) survey.std = 0.05 * np.ones_like(survey.dobs) survey.eps = 1e-5 * np.linalg.norm(survey.dobs) dmisAll = DataMisfit.l2_DataMisfit(survey) print '# of data: ', survey.dobs.shape class SimultaneousSrc(DC.Src.BaseSrc): """ Dipole source """ QW = None Q = None W = None def __init__(self, rxList, Q, W, **kwargs): SimPEG.Survey.BaseSrc.__init__(self, rxList, **kwargs)
def setUp(self): np.random.seed(0) # Define the inducing field parameter H0 = (50000, 90, 0) # Create a mesh dx = 5.0 hxind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)] hyind = [(dx, 5, -1.3), (dx, 5), (dx, 5, 1.3)] hzind = [(dx, 5, -1.3), (dx, 6)] 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.0, 20.0, 20) yr = np.linspace(-20.0, 20.0, 20) X, Y = np.meshgrid(xr, yr) # Move the observation points 5m above the topo Z = -np.exp((X ** 2 + Y ** 2) / 75 ** 2) + mesh.vectorNz[-1] + 5.0 # 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, mapping=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.0 survey.dobs = data survey.std = wd # Create sensitivity weights from our linear forward operator wr = np.sum(prob.G ** 2.0, axis=0) ** 0.5 wr = wr / np.max(wr) # Create a regularization reg = Regularization.Sparse(mesh, indActive=actv, mapping=idenMap) reg.cell_weights = wr # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.Wd = 1 / wd # Add directives to the inversion opt = Optimization.ProjectedGNCG(maxIter=100, lower=0.0, upper=1.0, 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(norms=([0, 1, 1, 1]), eps=(1e-3, 1e-3), f_min_change=1e-3, minGNiter=3) update_Jacobi = Directives.Update_lin_PreCond() self.inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, betaest, update_Jacobi])
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$)')
def run(plotIt=True): # Set up cylindrically symmetric mesh cs, ncx, ncz, npad = 10., 15, 25, 13 # padded cylindrical 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 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( ("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) plt.tight_layout(pad=1.5)
def run(plotIt=True): """ EM: FDEM: 1D: Inversion ======================= Here we will create and run a FDEM 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') 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: import matplotlib.pyplot as plt 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, mapping=mapping) try: from pymatsolver import PardisoSolver prb.Solver = PardisoSolver except ImportError: prb.Solver = SolverLU prb.pair(survey) std = 0.05 survey.makeSyntheticData(mtrue, std) survey.std = std survey.eps = np.linalg.norm(survey.dtrue)*1e-5 if plotIt: import matplotlib.pyplot as plt 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: import matplotlib.pyplot as plt 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') plt.show()
def run(plotIt=True, saveFig=False, cleanup=True): """ Run 1D inversions for a single sounding of the RESOLVE and SkyTEM bookpurnong data :param bool plotIt: show the plots? :param bool saveFig: save the figure :param bool cleanup: remove the downloaded results """ downloads, directory = download_and_unzip_data() resolve = h5py.File( os.path.sep.join([directory, "booky_resolve.hdf5"]), "r" ) skytem = h5py.File( os.path.sep.join([directory, "booky_skytem.hdf5"]), "r" ) river_path = resolve["river_path"].value # Choose a sounding location to invert xloc, yloc = 462100.0, 6196500.0 rxind_skytem = np.argmin( abs(skytem["xy"][:, 0]-xloc)+abs(skytem["xy"][:, 1]-yloc) ) rxind_resolve = np.argmin( abs(resolve["xy"][:, 0]-xloc)+abs(resolve["xy"][:, 1]-yloc) ) # Plot both resolve and skytem data on 2D plane fig = plt.figure(figsize=(13, 6)) title = ["RESOLVE In-phase 400 Hz", "SkyTEM High moment 156 $\mu$s"] ax1 = plt.subplot(121) ax2 = plt.subplot(122) axs = [ax1, ax2] out_re = Utils.plot2Ddata( resolve["xy"], resolve["data"][:, 0], ncontour=100, contourOpts={"cmap": "viridis"}, ax=ax1 ) vmin, vmax = out_re[0].get_clim() cb_re = plt.colorbar( out_re[0], ticks=np.linspace(vmin, vmax, 3), ax=ax1, fraction=0.046, pad=0.04 ) temp_skytem = skytem["data"][:, 5].copy() temp_skytem[skytem["data"][:, 5] > 7e-10] = 7e-10 out_sky = Utils.plot2Ddata( skytem["xy"][:, :2], temp_skytem, ncontour=100, contourOpts={"cmap": "viridis", "vmax": 7e-10}, ax=ax2 ) vmin, vmax = out_sky[0].get_clim() cb_sky = plt.colorbar( out_sky[0], ticks=np.linspace(vmin, vmax*0.99, 3), ax=ax2, format="%.1e", fraction=0.046, pad=0.04 ) cb_re.set_label("Bz (ppm)") cb_sky.set_label("dB$_z$ / dt (V/A-m$^4$)") for i, ax in enumerate(axs): xticks = [460000, 463000] yticks = [6195000, 6198000, 6201000] ax.set_xticks(xticks) ax.set_yticks(yticks) ax.plot(xloc, yloc, 'wo') ax.plot(river_path[:, 0], river_path[:, 1], 'k', lw=0.5) ax.set_aspect("equal") if i == 1: ax.plot( skytem["xy"][:, 0], skytem["xy"][:, 1], 'k.', alpha=0.02, ms=1 ) ax.set_yticklabels([str(" ") for f in yticks]) else: ax.plot( resolve["xy"][:, 0], resolve["xy"][:, 1], 'k.', alpha=0.02, ms=1 ) ax.set_yticklabels([str(f) for f in yticks]) ax.set_ylabel("Northing (m)") ax.set_xlabel("Easting (m)") ax.set_title(title[i]) ax.axis('equal') # plt.tight_layout() if saveFig is True: fig.savefig("resolve_skytem_data.png", dpi=600) # ------------------ Mesh ------------------ # # Step1: Set 2D cylindrical mesh cs, ncx, ncz, npad = 1., 10., 10., 20 hx = [(cs, ncx), (cs, npad, 1.3)] npad = 12 temp = np.logspace(np.log10(1.), np.log10(12.), 19) temp_pad = temp[-1] * 1.3 ** np.arange(npad) hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad] mesh = Mesh.CylMesh([hx, 1, hz], '00C') active = mesh.vectorCCz < 0. # Step2: Set a SurjectVertical1D mapping # Note: this sets our inversion model as 1D log conductivity # below subsurface active = mesh.vectorCCz < 0. actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap sig_half = 1e-1 sig_air = 1e-8 sigma = np.ones(mesh.nCz)*sig_air sigma[active] = sig_half # Initial and reference model m0 = np.log(sigma[active]) # ------------------ RESOLVE Forward Simulation ------------------ # # Step3: Invert Resolve data # Bird height from the surface b_height_resolve = resolve["src_elevation"].value src_height_resolve = b_height_resolve[rxind_resolve] # Set Rx (In-phase and Quadrature) rxOffset = 7.86 bzr = EM.FDEM.Rx.Point_bSecondary( np.array([[rxOffset, 0., src_height_resolve]]), orientation='z', component='real' ) bzi = EM.FDEM.Rx.Point_b( np.array([[rxOffset, 0., src_height_resolve]]), orientation='z', component='imag' ) # Set Source (In-phase and Quadrature) frequency_cp = resolve["frequency_cp"].value freqs = frequency_cp.copy() srcLoc = np.array([0., 0., src_height_resolve]) srcList = [EM.FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs] # Set FDEM survey (In-phase and Quadrature) survey = EM.FDEM.Survey(srcList) prb = EM.FDEM.Problem3D_b( mesh, sigmaMap=mapping, Solver=Solver ) prb.pair(survey) # ------------------ RESOLVE Inversion ------------------ # # Primary field bp = - mu_0/(4*np.pi*rxOffset**3) # Observed data cpi_inds = [0, 2, 6, 8, 10] cpq_inds = [1, 3, 7, 9, 11] dobs_re = np.c_[ resolve["data"][rxind_resolve, :][cpi_inds], resolve["data"][rxind_resolve, :][cpq_inds] ].flatten() * bp * 1e-6 # Uncertainty std = np.repeat(np.r_[np.ones(3)*0.1, np.ones(2)*0.15], 2) floor = 20 * abs(bp) * 1e-6 uncert = abs(dobs_re) * std + floor # Data Misfit survey.dobs = dobs_re dmisfit = DataMisfit.l2_DataMisfit(survey) dmisfit.W = 1./uncert # Regularization regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh, mapping=Maps.IdentityMap(regMesh)) # Optimization opt = Optimization.InexactGaussNewton(maxIter=5) # statement of the inverse problem invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion directives and parameters target = Directives.TargetMisfit() # stop when we hit target misfit invProb.beta = 2. # betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) inv = Inversion.BaseInversion(invProb, directiveList=[target]) reg.alpha_s = 1e-3 reg.alpha_x = 1. reg.mref = m0.copy() opt.LSshorten = 0.5 opt.remember('xc') # run the inversion mopt_re = inv.run(m0) dpred_re = invProb.dpred # ------------------ SkyTEM Forward Simulation ------------------ # # Step4: Invert SkyTEM data # Bird height from the surface b_height_skytem = skytem["src_elevation"].value src_height = b_height_skytem[rxind_skytem] srcLoc = np.array([0., 0., src_height]) # Radius of the source loop area = skytem["area"].value radius = np.sqrt(area/np.pi) rxLoc = np.array([[radius, 0., src_height]]) # Parameters for current waveform t0 = skytem["t0"].value times = skytem["times"].value waveform_skytem = skytem["waveform"].value offTime = t0 times_off = times - t0 # Note: we are Using theoretical VTEM waveform, # but effectively fits SkyTEM waveform peakTime = 1.0000000e-02 a = 3. dbdt_z = EM.TDEM.Rx.Point_dbdt( locs=rxLoc, times=times_off[:-3]+offTime, orientation='z' ) # vertical db_dt rxList = [dbdt_z] # list of receivers srcList = [ EM.TDEM.Src.CircularLoop( rxList, loc=srcLoc, radius=radius, orientation='z', waveform=EM.TDEM.Src.VTEMWaveform( offTime=offTime, peakTime=peakTime, a=3. ) ) ] # solve the problem at these times timeSteps = [ (peakTime/5, 5), ((offTime-peakTime)/5, 5), (1e-5, 5), (5e-5, 5), (1e-4, 10), (5e-4, 15) ] prob = EM.TDEM.Problem3D_e( mesh, timeSteps=timeSteps, sigmaMap=mapping, Solver=Solver ) survey = EM.TDEM.Survey(srcList) prob.pair(survey) src = srcList[0] rx = src.rxList[0] wave = [] for time in prob.times: wave.append(src.waveform.eval(time)) wave = np.hstack(wave) out = survey.dpred(m0) # plot the waveform fig = plt.figure(figsize=(5, 3)) times_off = times-t0 plt.plot(waveform_skytem[:, 0], waveform_skytem[:, 1], 'k.') plt.plot(prob.times, wave, 'k-', lw=2) plt.legend(("SkyTEM waveform", "Waveform (fit)"), fontsize=10) for t in rx.times: plt.plot(np.ones(2)*t, np.r_[-0.03, 0.03], 'k-') plt.ylim(-0.1, 1.1) plt.grid(True) plt.xlabel("Time (s)") plt.ylabel("Normalized current") if saveFig: fig.savefig("skytem_waveform", dpi=200) # Observed data dobs_sky = skytem["data"][rxind_skytem, :-3] * area # ------------------ SkyTEM Inversion ------------------ # # Uncertainty std = 0.12 floor = 7.5e-12 uncert = abs(dobs_sky) * std + floor # Data Misfit survey.dobs = -dobs_sky dmisfit = DataMisfit.l2_DataMisfit(survey) uncert = 0.12*abs(dobs_sky) + 7.5e-12 dmisfit.W = Utils.sdiag(1./uncert) # Regularization regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh, mapping=Maps.IdentityMap(regMesh)) # Optimization opt = Optimization.InexactGaussNewton(maxIter=5) # statement of the inverse problem invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Directives and Inversion Parameters target = Directives.TargetMisfit() # betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) invProb.beta = 20. inv = Inversion.BaseInversion(invProb, directiveList=[target]) reg.alpha_s = 1e-1 reg.alpha_x = 1. opt.LSshorten = 0.5 opt.remember('xc') reg.mref = mopt_re # Use RESOLVE model as a reference model # run the inversion mopt_sky = inv.run(m0) dpred_sky = invProb.dpred # Plot the figure from the paper plt.figure(figsize=(12, 8)) fs = 13 # fontsize matplotlib.rcParams['font.size'] = fs ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2) ax1 = plt.subplot2grid((2, 2), (0, 1)) ax2 = plt.subplot2grid((2, 2), (1, 1)) # Recovered Models sigma_re = np.repeat(np.exp(mopt_re), 2, axis=0) sigma_sky = np.repeat(np.exp(mopt_sky), 2, axis=0) z = np.repeat(mesh.vectorCCz[active][1:], 2, axis=0) z = np.r_[mesh.vectorCCz[active][0], z, mesh.vectorCCz[active][-1]] ax0.semilogx(sigma_re, z, 'k', lw=2, label="RESOLVE") ax0.semilogx(sigma_sky, z, 'b', lw=2, label="SkyTEM") ax0.set_ylim(-50, 0) # ax0.set_xlim(5e-4, 1e2) ax0.grid(True) ax0.set_ylabel("Depth (m)") ax0.set_xlabel("Conducivity (S/m)") ax0.legend(loc=3) ax0.set_title("(a) Recovered Models") # RESOLVE Data ax1.loglog( frequency_cp, dobs_re.reshape((5, 2))[:, 0]/bp*1e6, 'k-', label="Obs (real)" ) ax1.loglog( frequency_cp, dobs_re.reshape((5, 2))[:, 1]/bp*1e6, 'k--', label="Obs (imag)" ) ax1.loglog( frequency_cp, dpred_re.reshape((5, 2))[:, 0]/bp*1e6, 'k+', ms=10, markeredgewidth=2., label="Pred (real)" ) ax1.loglog( frequency_cp, dpred_re.reshape((5, 2))[:, 1]/bp*1e6, 'ko', ms=6, markeredgecolor='k', markeredgewidth=0.5, label="Pred (imag)" ) ax1.set_title("(b) RESOLVE") ax1.set_xlabel("Frequency (Hz)") ax1.set_ylabel("Bz (ppm)") ax1.grid(True) ax1.legend(loc=3, fontsize=11) # SkyTEM data ax2.loglog(times_off[3:]*1e6, dobs_sky/area, 'b-', label="Obs") ax2.loglog( times_off[3:]*1e6, -dpred_sky/area, 'bo', ms=4, markeredgecolor='k', markeredgewidth=0.5, label="Pred" ) ax2.set_xlim(times_off.min()*1e6*1.2, times_off.max()*1e6*1.1) ax2.set_xlabel("Time ($\mu s$)") ax2.set_ylabel("dBz / dt (V/A-m$^4$)") ax2.set_title("(c) SkyTEM High-moment") ax2.grid(True) ax2.legend(loc=3) a3 = plt.axes([0.86, .33, .1, .09], facecolor=[0.8, 0.8, 0.8, 0.6]) a3.plot(prob.times*1e6, wave, 'k-') a3.plot( rx.times*1e6, np.zeros_like(rx.times), 'k|', markeredgewidth=1, markersize=12 ) a3.set_xlim([prob.times.min()*1e6*0.75, prob.times.max()*1e6*1.1]) a3.set_title('(d) Waveform', fontsize=11) a3.set_xticks([prob.times.min()*1e6, t0*1e6, prob.times.max()*1e6]) a3.set_yticks([]) # a3.set_xticklabels(['0', '2e4']) a3.set_xticklabels(['-1e4', '0', '1e4']) plt.tight_layout() if saveFig: plt.savefig("booky1D_time_freq.png", dpi=600) if plotIt: plt.show() resolve.close() skytem.close() if cleanup: print( os.path.split(directory)[:-1]) os.remove( os.path.sep.join( directory.split()[:-1] + ["._bookpurnong_inversion"] ) ) os.remove(downloads) shutil.rmtree(directory)
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=True, alpha_s=1e-4, alpha_x=1., alpha_y=1., alpha_z=1., ): """ Run DC 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.Simple(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.Tikhonov(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 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 update_Jacobi = Directives.UpdatePreconditioner() if use_sensitivity_weight: updateSensW = Directives.UpdateSensitivityWeights() directiveList = [ beta, betaest, target, updateSensW, update_Jacobi ] else: directiveList = [ beta, betaest, target, update_Jacobi ] 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, 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) reg.mref = driver.mref[dynamic] reg.cell_weights = wr * mesh.vol[active] reg.norms = driver.lpnorms # Specify how the optimization will proceed opt = Optimization.ProjectedGNCG(maxIter=150, lower=driver.bounds[0], upper=driver.bounds[1], maxIterLS=20, 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() # 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-2, maxIRLSiter=20, minGNiter=5) # Preconditioning refreshing for each IRLS iteration update_Jacobi = Directives.Update_lin_PreCond() # 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 * IRLS.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$)')
def run(plotIt=True): # Create a mesh dx = 5. hxind = [(dx, 5, -1.3), (dx, 15), (dx, 5, 1.3)] hyind = [(dx, 5, -1.3), (dx, 15), (dx, 5, 1.3)] hzind = [(dx, 5, -1.3), (dx, 7), (3.5, 1), (2, 5)] 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] # We would usually load a topofile topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)] # Go from topo to array of indices of active cells actv = Utils.surface2ind_topo(mesh, topo, 'N') actv = np.where(actv)[0] nC = len(actv) # Create and array of observation points xr = np.linspace(-30., 30., 20) yr = np.linspace(-30., 30., 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] + 0.1 # Create a GRAVsurvey rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)] rxLoc = PF.BaseGrav.RxObs(rxLoc) 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-5):(midx-1), (midy-2):(midy+2), -10:-6] = 0.75 model[(midx+1):(midx+5), (midy-2):(midy+2), -10:-6] = -0.75 model = Utils.mkvc(model) model = model[actv] # Create active map to go from reduce set to full actvMap = Maps.InjectActiveCells(mesh, actv, -100) # 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(model) # Add noise and uncertainties # We add some random Gaussian noise (1nT) data = d + np.random.randn(len(d))*1e-3 wd = np.ones(len(data))*1e-3 # Assign flat uncertainties survey.dobs = data survey.std = wd survey.mtrue = model # Create sensitivity weights from our linear forward operator rxLoc = survey.srcField.rxList[0].locs 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] # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = Utils.sdiag(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) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e-1) # Here is where the norms are applied # Use pick a threshold parameter empirically based on the distribution of # model parameters IRLS = Directives.Update_IRLS( f_min_change=1e-4, maxIRLSiter=30, coolEpsFact=1.5, beta_tol=1e-1, ) saveDict = Directives.SaveOutputEveryIteration(save_txt=False) update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion( invProb, directiveList=[IRLS, betaest, update_Jacobi, saveDict] ) # Run the inversion m0 = np.ones(nC)*1e-4 # Starting model mrec = inv.run(m0) if plotIt: # Here is the recovered susceptibility model ypanel = midx zpanel = -7 m_l2 = actvMap * invProb.l2model m_l2[m_l2 == -100] = np.nan m_lp = actvMap * mrec m_lp[m_lp == -100] = np.nan m_true = actvMap * model m_true[m_true == -100] = np.nan vmin, vmax = mrec.min(), mrec.max() # Plot the data Utils.PlotUtils.plot2Ddata(rxLoc, data) plt.figure() # Plot L2 model ax = plt.subplot(321) mesh.plotSlice(m_l2, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan l2-model.') plt.gca().set_aspect('equal') plt.ylabel('y') ax.xaxis.set_visible(False) plt.gca().set_aspect('equal', adjustable='box') # Vertical section ax = plt.subplot(322) mesh.plotSlice(m_l2, ax=ax, normal='Y', ind=midx, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W l2-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box') # Plot Lp model ax = plt.subplot(323) mesh.plotSlice(m_lp, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan lp-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('y') plt.gca().set_aspect('equal', adjustable='box') # Vertical section ax = plt.subplot(324) mesh.plotSlice(m_lp, ax=ax, normal='Y', ind=midx, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W lp-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box') # Plot True model ax = plt.subplot(325) mesh.plotSlice(m_true, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan true model.') plt.gca().set_aspect('equal') plt.xlabel('x') plt.ylabel('y') plt.gca().set_aspect('equal', adjustable='box') # Vertical section ax = plt.subplot(326) mesh.plotSlice(m_true, ax=ax, normal='Y', ind=midx, grid=True, clim=(vmin, vmax)) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W true model.') plt.gca().set_aspect('equal') plt.xlabel('x') plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box') # Plot convergence curves fig, axs = plt.figure(), plt.subplot() axs.plot(saveDict.phi_d, 'k', lw=2) axs.plot( np.r_[IRLS.iterStart, IRLS.iterStart], np.r_[0, np.max(saveDict.phi_d)], 'k:' ) twin = axs.twinx() twin.plot(saveDict.phi_m, 'k--', lw=2) axs.text( IRLS.iterStart, np.max(saveDict.phi_d)/2., 'IRLS Steps', va='bottom', ha='center', rotation='vertical', size=12, bbox={'facecolor': 'white'} ) axs.set_ylabel('$\phi_d$', size=16, rotation=0) axs.set_xlabel('Iterations', size=14) twin.set_ylabel('$\phi_m$', size=16, rotation=0)
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): """ 1D FDEM and TDEM inversions =========================== This example is used in the paper Heagy et al 2016 (in prep) """ # 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.]]) bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real') bzr = 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 = [] [srcList.append(FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z')) for freq in freqs] surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, mapping=mapping) 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() inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest, target]) 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(rxlocs, times, 'bz') 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, mapping=mapping) prbTD.timeSteps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)] prbTD.pair(surveyTD) prbTD.Solver = SolverLU 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) # Inversion Directives beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest, target]) 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) if plotIt: import matplotlib fig = 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) ax0.semilogx(np.exp(moptFD), mesh.vectorCCz[active], 'bo', ms=6) ax0.semilogx(np.exp(moptTD), mesh.vectorCCz[active], 'r*', ms=10) 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(['True', 'FDEM', 'TDEM'], 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) ax1.plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2) dpredFD = surveyFD.dpred(moptTD) ax1.loglog(freqs, -dpredFD[::2], 'bo', ms=6) ax1.loglog(freqs, -dpredFD[1::2], 'b+', markeredgewidth=2., ms=10) ax2.loglog(times, surveyTD.dobs, 'k-', lw=2) ax2.loglog(times, surveyTD.dpred(moptTD), 'r*', ms=10) ax2.set_xlim(times.min(), times.max()) # 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(("Obs", "Pred"), fontsize=fs) ax1.legend(("Obs (real)", "Obs (imag)", "Pred (real)", "Pred (imag)"), fontsize=fs) ax1.set_xlim(freqs.max(), freqs.min()) 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) plt.show()
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 setUp(self): ndv = -100 # Create a self.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)] self.mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC') # Get index of the center midx = int(self.mesh.nCx/2) midy = int(self.mesh.nCy/2) # Lets create a simple Gaussian topo and set the active cells [xx, yy] = np.meshgrid(self.mesh.vectorNx, self.mesh.vectorNy) zz = -np.exp((xx**2 + yy**2) / 75**2) + self.mesh.vectorNz[-1] # Go from topo to actv cells topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)] actv = Utils.surface2ind_topo(self.mesh, topo, 'N') actv = np.where(actv)[0] # Create active map to go from reduce space to full self.actvMap = Maps.InjectActiveCells(self.mesh, actv, -100) nC = len(actv) # Create and array of observation points xr = np.linspace(-20., 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) + self.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((self.mesh.nCx, self.mesh.nCy, self.mesh.nCz)) model[(midx-2):(midx+2), (midy-2):(midy+2), -6:-2] = 0.5 model = Utils.mkvc(model) self.model = model[actv] # Create active map to go from reduce set to full actvMap = Maps.InjectActiveCells(self.mesh, actv, ndv) # Create reduced identity map idenMap = Maps.IdentityMap(nP=nC) # Create the forward model operator prob = PF.Gravity.GravityIntegral( self.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(self.mesh, locXYZ, actv, 2., 2.) wr = wr**2. # Create a regularization reg = Regularization.Sparse(self.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 = 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-4, minGNiter=1) update_Jacobi = Directives.UpdatePreconditioner() self.inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, update_Jacobi])
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 run(plotIt=True): 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}$'])
prob.solverOpts['accuracyTol'] = 1e-4 # Pair the survey and problem survey.pair(prob) # Create a regularization function, in this case l2l2 reg = Regularization.Simple(mesh, indActive=surf) reg.mref = np.zeros(nC) # Specify how the optimization will proceed, set susceptibility bounds to inf 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)
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]) if plotIt is True: import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1, figsize=(3, 6)) plt.semilogx(sigma[active], mesh.vectorCCz[active]) ax.set_ylim(-600, 0) ax.set_xlim(1e-4, 1e-2) 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 = 1e-3 rx = EM.TDEM.Rx(np.array([[rxOffset, 0., 30]]), np.logspace(-5, -3, 31), 'bz') src = EM.TDEM.Src.MagDipole([rx], loc=np.array([0., 0., 80])) survey = EM.TDEM.Survey([src]) prb = EM.TDEM.Problem3D_b(mesh, mapping=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) if plotIt: import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 1, figsize = (10, 6)) ax.loglog(rx.times, survey.dtrue, 'b.-') ax.loglog(rx.times, survey.dobs, '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=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) reg.alpha_s = 1e-2 reg.alpha_x = 1. prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') mopt = inv.run(m0) if plotIt: import matplotlib.pyplot as plt 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(-600, 0) ax.set_xlim(1e-4, 1e-2) 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}$']) 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])
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 ] )
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
def run(plotIt=True): # Define the inducing field parameter H0 = (50000, 90, 0) # Create a mesh dx = 5. hxind = [(dx, 5, -1.3), (dx, 10), (dx, 5, 1.3)] hyind = [(dx, 5, -1.3), (dx, 10), (dx, 5, 1.3)] hzind = [(dx, 5, -1.3), (dx, 10)] 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] # We would usually load a topofile topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)] # Go from topo to actv cells 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) 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(model) # Add noise and uncertainties # We add some random Gaussian noise (1nT) data = d + np.random.randn(len(d)) wd = np.ones(len(data))*1. # Assign flat uncertainties survey.dobs = data survey.std = wd survey.mtrue = model # Create sensitivity weights from our linear forward operator rxLoc = survey.srcField.rxList[0].locs 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 = [0, 1, 1, 1] 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 # 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.Update_lin_PreCond() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, betaest, update_Jacobi]) # Run the inversion m0 = np.ones(nC)*1e-4 # Starting model mrec = inv.run(m0) if plotIt: # Here is the recovered susceptibility model ypanel = midx zpanel = -5 m_l2 = actvMap * IRLS.l2model m_l2[m_l2 == -100] = np.nan m_lp = actvMap * mrec m_lp[m_lp == -100] = np.nan m_true = actvMap * model m_true[m_true == -100] = np.nan # Plot the data PF.Magnetics.plot_obs_2D(rxLoc, d=d) plt.figure() # Plot L2 model ax = plt.subplot(321) mesh.plotSlice(m_l2, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan l2-model.') plt.gca().set_aspect('equal') plt.ylabel('y') ax.xaxis.set_visible(False) plt.gca().set_aspect('equal', adjustable='box') # Vertica section ax = plt.subplot(322) mesh.plotSlice(m_l2, ax=ax, normal='Y', ind=midx, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W l2-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box') # Plot Lp model ax = plt.subplot(323) mesh.plotSlice(m_lp, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan lp-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('y') plt.gca().set_aspect('equal', adjustable='box') # Vertical section ax = plt.subplot(324) mesh.plotSlice(m_lp, ax=ax, normal='Y', ind=midx, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W lp-model.') plt.gca().set_aspect('equal') ax.xaxis.set_visible(False) plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box') # Plot True model ax = plt.subplot(325) mesh.plotSlice(m_true, ax=ax, normal='Z', ind=zpanel, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCy[ypanel], mesh.vectorCCy[ypanel]]), color='w') plt.title('Plan true model.') plt.gca().set_aspect('equal') plt.xlabel('x') plt.ylabel('y') plt.gca().set_aspect('equal', adjustable='box') # Vertical section ax = plt.subplot(326) mesh.plotSlice(m_true, ax=ax, normal='Y', ind=midx, grid=True, clim=(model.min(), model.max())) plt.plot(([mesh.vectorCCx[0], mesh.vectorCCx[-1]]), ([mesh.vectorCCz[zpanel], mesh.vectorCCz[zpanel]]), color='w') plt.title('E-W true model.') plt.gca().set_aspect('equal') plt.xlabel('x') plt.ylabel('z') plt.gca().set_aspect('equal', adjustable='box')
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
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()
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 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()