def setUp(self): url = 'https://storage.googleapis.com/simpeg/tests/dc_utils/' cloudfiles = [ 'mesh3d.msh', '2spheres_conmodel.npy', 'rhoA_GIF_dd.txt', 'rhoA_GIF_dp.txt', 'rhoA_GIF_pd.txt', 'rhoA_GIF_pp.txt' ] self.basePath = os.path.expanduser('~/Downloads/TestDCUtilsHalfSpace') self.files = io_utils.download( [url+f for f in cloudfiles], folder=self.basePath, overwrite=True ) # Load Mesh mesh_file = os.path.sep.join([self.basePath, 'mesh3d.msh']) mesh = Mesh.load_mesh(mesh_file) self.mesh = mesh # Load Model model_file = os.path.sep.join([self.basePath, '2spheres_conmodel.npy']) model = np.load(model_file) self.model = model xmin, xmax = -15., 15. ymin, ymax = 0., 0. zmin, zmax = -0.25, -0.25 xyz = np.array([[xmin, ymin, zmin], [xmax, ymax, zmax]]) self.xyz = xyz self.survey_a = 1. self.survey_b = 1. self.survey_n = 10 self.plotIt = False
def simulate_prism( self, component, inclination, declination, length, dx, B0, kappa, depth, profile, fixed_scale, show_halfwidth, prism_dx, prism_dy, prism_dz, prism_inclination, prism_declination, ): self.component = component self.inclination = -inclination # -ve accounts for LH modeling in SimPEG self.declination = declination self.length = length self.dx = dx self.B0 = B0 self.kappa = kappa self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth # prism parameter self.prism = self.get_prism( prism_dx, prism_dy, prism_dz, 0, 0, -depth, prism_inclination, prism_declination, ) nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = Mesh.TensorMesh((hx, hy), "CC") z = np.r_[1.0] B = np.r_[B0, -inclination, declination] # -ve accounts for LH modeling in SimPEG # Project to the direction of earth field if component == "Bt": uType = "tf" elif component == "Bx": uType = "bx" elif component == "By": uType = "by" elif component == "Bz": uType = "bz" xyz = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) self.survey = createMagSurvey(np.c_[xyz, np.ones(self.mesh.nC)], B) self.prob = problem() self.prob.prism = self.prism self.prob.survey = self.survey self.prob.susc = kappa self.prob.uType, self.prob.mType = uType, "induced" self.data = self.prob.fields()[0] # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = Utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile]
# receivers rx_x = np.linspace(-175., 175., 8) rx_y = rx_x.copy() rx_z = np.r_[175.] rx_locs = Utils.ndgrid(rx_x, rx_y, rx_z) # mesh csx, ncx, npadx = 25., 16, 10 csz, ncz, npadz = 25., 8, 10 pf = 1.5 # primary mesh hx = [(csx, ncx), (csx, npadx, pf)] hz = [(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)] meshp = Mesh.CylMesh([hx, 1., hz], x0='0CC') # secondary mesh h = [(csz, npadz-4, -pf), (csz, ncz), (csz, npadz-4, pf)] meshs = Mesh.TensorMesh(3*[h], x0 = 'CCC') # mappings primaryMapping = ( Maps.ExpMap(meshp) * Maps.SurjectFull(meshp) * Maps.Projection(nP=8, index=[0]) ) mapping = ( Maps.ExpMap(meshs) * Maps.ParametrizedBlockInLayer(meshs) *
# scale = Utils.mkvc(homogMap.P.sum(axis=0)) # for ii in range(nC): # wr[ii] *= scale[ii] wr = (wr / np.max(wr)) wr = wr else: wr = Mesh.TensorMesh.readModelUBC(mesh, work_dir + dsep + wgtfile) wr = wr[actv] wr = wr**2. Mesh.TensorMesh.writeModelUBC(mesh, work_dir + out_dir + 'SensWeights.den', actvMap * (homogMap.P * wr)) idenMap = Maps.IdentityMap(nP=nC) regMesh = Mesh.TensorMesh([nC]) # Create a regularization reg = Regularization.Sparse(regMesh, mapping=idenMap) reg.norms = driver.lpnorms if driver.eps is not None: reg.eps_p = driver.eps[0] reg.eps_q = driver.eps[1] reg.cell_weights = wr #driver.cell_weights*mesh.vol**0.5 reg.mref = mstart dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / survey.std
def readSeepageModel(fname, mesh=None, xsurf=None, ysurf=None): fluiddata = pd.read_csv(fname) header = fluiddata.keys() xyz = np.c_[fluiddata['X (m)'].values, fluiddata['Y (m)'].values] h = fluiddata['Total Head (m)'].values Ux = fluiddata['X-Velocity Magnitude (m/sec)'].values Uy = fluiddata['Y-Velocity Magnitude (m/sec)'].values Gradx = fluiddata['X-Gradient'].values Grady = fluiddata['Y-Gradient'].values Pressure = fluiddata['Pressure Head (m)'].values Sw = fluiddata[fluiddata.keys()[17]].values Kx = fluiddata["X-Conductivity (m/sec)"] Ky = fluiddata["Y-Conductivity (m/sec)"] if mesh is None: # TODO: this is a specific set up ... xmin, ymin = xyz[:, 0].min(), xyz[:, 1].min() cs = 0.5 ncx = 152 * 2 ncy = 36 * 2 npad = 5 hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, ncy)] mesh = Mesh.TensorMesh([hx, hy], x0=[xmin, ymin]) mesh._x0 = np.r_[xmin - mesh.hx[:10].sum(), xmin - mesh.hy[:10].sum()] # ... xsurf = np.r_[-1e10, 55, 90, 94, 109, 112, 126.5, +1e10] ysurf = np.r_[27.5, 27.5, 43.2, 43.2, 35, 35, 27.5, 27.5] yup = np.ones_like(ysurf) * 45 actind = Utils.surface2ind_topo(mesh, np.c_[xsurf, ysurf]) waterheight = 40. waterind = ((np.logical_and(~actind, mesh.gridCC[:, 1] < 40.)) & (mesh.gridCC[:, 0] < 90.)) F_hlin = LinearNDInterpolator(xyz, h) hccIn = F_hlin(mesh.gridCC[actind, :]) F_hnear = NearestNDInterpolator(mesh.gridCC[actind, :], hccIn) hcc = F_hnear(mesh.gridCC) fluiddata = { "xyz": xyz, "h": h, "Sw": Sw, "Kx": Kx, "Ky": Ky, "P": Pressure, "Ux": Ux, "Uy": Uy, "Gradx": Gradx, "Grady": Grady, "hcc": hcc, "mesh": mesh, "actind": actind, "waterind": waterind, "xsurf": xsurf, "ysurf": ysurf, "yup": yup } return fluiddata
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: fig, ax = plt.subplots(1, 1, figsize=(3, 6)) plt.semilogx(sigma[active], mesh.vectorCCz[active]) ax.set_ylim(-500, 0) ax.set_xlim(1e-3, 1e-1) ax.set_xlabel('Conductivity (S/m)', fontsize=14) ax.set_ylabel('Depth (m)', fontsize=14) ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) rxOffset = 10. bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., 1e-3]]), orientation='z', component='imag') freqs = np.logspace(1, 3, 10) srcLoc = np.array([0., 0., 10.]) srcList = [ EM.FDEM.Src.MagDipole([bzi], freq, srcLoc, orientation='Z') for freq in freqs ] survey = EM.FDEM.Survey(srcList) prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prb.pair(survey) std = 0.05 survey.makeSyntheticData(mtrue, std) survey.std = std survey.eps = np.linalg.norm(survey.dtrue) * 1e-5 if plotIt: fig, ax = plt.subplots(1, 1, figsize=(6, 6)) ax.semilogx(freqs, survey.dtrue[:freqs.size], 'b.-') ax.semilogx(freqs, survey.dobs[:freqs.size], 'r.-') ax.legend(('Noisefree', '$d^{obs}$'), fontsize=16) ax.set_xlabel('Time (s)', fontsize=14) ax.set_ylabel('$B_z$ (T)', fontsize=16) ax.set_xlabel('Time (s)', fontsize=14) ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) dmisfit = DataMisfit.l2_DataMisfit(survey) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Tikhonov(regMesh) opt = Optimization.InexactGaussNewton(maxIter=6) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Create an inversion object beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest]) m0 = np.log(np.ones(mtrue.size) * sig_half) reg.alpha_s = 1e-3 reg.alpha_x = 1. prb.counter = opt.counter = Utils.Counter() opt.LSshorten = 0.5 opt.remember('xc') mopt = inv.run(m0) if plotIt: fig, ax = plt.subplots(1, 1, figsize=(3, 6)) plt.semilogx(sigma[active], mesh.vectorCCz[active]) plt.semilogx(np.exp(mopt), mesh.vectorCCz[active]) ax.set_ylim(-500, 0) ax.set_xlim(1e-3, 1e-1) ax.set_xlabel('Conductivity (S/m)', fontsize=14) ax.set_ylabel('Depth (m)', fontsize=14) ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'], loc='best')
def run(N=100, plotIt=True): np.random.seed(1) std_noise = 1e-2 mesh = Mesh.TensorMesh([N]) m0 = np.ones(mesh.nC) * 1e-4 mref = np.zeros(mesh.nC) 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.dobs = prob.fields(mtrue) + std_noise * np.random.randn(nk) wd = np.ones(nk) * std_noise # Distance weighting wr = np.sum(prob.G**2., axis=0)**0.5 wr = wr / np.max(wr) dmis = DataMisfit.l2_DataMisfit(survey) dmis.Wd = 1. / wd betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e-2) reg = Regularization.Sparse(mesh) reg.mref = mref reg.cell_weights = wr reg.mref = np.zeros(mesh.nC) opt = Optimization.ProjectedGNCG(maxIter=100, lower=-2., upper=2., maxIterLS=20, maxIterCG=10, tolCG=1e-3) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) update_Jacobi = Directives.Update_lin_PreCond() # Set the IRLS directive, penalize the lowest 25 percentile of model values # Start with an l2-l2, then switch to lp-norms norms = [0., 0., 2., 2.] IRLS = Directives.Update_IRLS(norms=norms, prctile=25, maxIRLSiter=15, minGNiter=3) inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, betaest, update_Jacobi]) # Run inversion mrec = inv.run(m0) print("Final misfit:" + str(invProb.dmisfit.eval(mrec))) 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(mesh.vectorCCx, mtrue, 'b-') axes[1].plot(mesh.vectorCCx, reg.l2model, 'r-') # axes[1].legend(('True Model', 'Recovered Model')) axes[1].set_ylim(-1.0, 1.25) axes[1].plot(mesh.vectorCCx, mrec, 'k-', lw=2) axes[1].legend(('True Model', 'Smooth l2-l2', 'Sparse lp: {0}, lqx: {1}'.format(*reg.norms)), fontsize=12) return prob, survey, mesh, mrec
from sklearn.mixture import GaussianMixture from SimPEG import DataMisfit, Regularization, Optimization, InvProblem, Directives, Inversion import SimPEG import scipy.sparse as sp #2D model csx, csy, csz = 0.25, 0.25, 0.25 # Number of core cells in each directiPon s ncx, ncz = 2**7 - 24, 2**7 - 12 # Number of padding cells to add in each direction npad = 12 # Vectors of cell lengthts in each direction hx = [(csx, npad, -1.5), (csx, ncx), (csx, npad, 1.5)] hz = [(csz, npad, -1.5), (csz, ncz)] # Create mesh mesh = Mesh.TensorMesh([hx, hz], x0="CN") # Map mesh coordinates from local to UTM coordiantes #mesh.x0[2] = mesh.x0[2]-mesh.vectorCCz[-npad-1] mesh.x0[1] = mesh.x0[1] + csz / 2. #mesh.x0[0] = mesh.x0[0]+csx/2. #mesh.plotImage(np.ones(mesh.nC)*np.nan, grid=True) #mesh.plotImage(np.ones(mesh.nC)*np.nan, grid=True) #plt.gca().set_xlim([-20,20]) #plt.gca().set_ylim([-15,0]) #mesh.plotGrid() #plt.gca().set_aspect('equal') #plt.show() print "Mesh Size: ", mesh.nC #Model Creation
def setUp(self): cs = 0.5 npad = 11 hx = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)] hy = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)] hz = [(cs, npad, -1.5), (cs, 15), (cs, npad, 1.5)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCC") sigma = np.ones(mesh.nC)*1e-2 # Set up survey parameters for numeric solution x = mesh.vectorNx[(mesh.vectorNx > -75.) & (mesh.vectorNx < 75.)] y = mesh.vectorNy[(mesh.vectorNy > -75.) & (mesh.vectorNy < 75.)] Aloc = np.r_[1.25, 0., 0.] Bloc = np.r_[-1.25, 0., 0.] M = Utils.ndgrid(x-25., y, np.r_[0.]) N = Utils.ndgrid(x+25., y, np.r_[0.]) rx = DC.Rx.Dipole(M, N) src = DC.Src.Dipole([rx], Aloc, Bloc) survey = DC.Survey([src]) # Create Dipole Obj for Analytic Solution edipole = fdem.ElectricDipoleWholeSpace( sigma=1e-2, # conductivity of 1 S/m mu=mu_0, # permeability of free space (this is the default) epsilon=epsilon_0, # permittivity of free space (this is the default) location=np.r_[0., 0., 0.], # location of the dipole orientation='X', # horizontal dipole (can also be a unit-vector) quasistatic=True, # don't use the quasistatic assumption frequency=0.0, # DC length=2.5 # length of dipole ) # evaluate the electric field and current density Ex_analytic = np.zeros_like([mesh.nEx,1]) Ey_analytic = np.zeros_like([mesh.nEy,1]) Ez_analytic = np.zeros_like([mesh.nEz,1]) Ex_analytic = np.real(edipole.electric_field(mesh.gridEx))[:,0] Ey_analytic = np.real(edipole.electric_field(mesh.gridEy))[:,1] Ez_analytic = np.real(edipole.electric_field(mesh.gridEz))[:,2] E_analytic = np.hstack([Ex_analytic,Ey_analytic,Ez_analytic]) Jx_analytic = np.zeros_like([mesh.nEx,1]) Jy_analytic = np.zeros_like([mesh.nEy,1]) Jz_analytic = np.zeros_like([mesh.nEz,1]) Jx_analytic = np.real(edipole.current_density(mesh.gridEx))[:,0] Jy_analytic = np.real(edipole.current_density(mesh.gridEy))[:,1] Jz_analytic = np.real(edipole.current_density(mesh.gridEz))[:,2] J_analytic = np.hstack([Jx_analytic,Jy_analytic,Jz_analytic]) # Find edges at which to compare solutions edgeGrid = np.vstack([mesh.gridEx,mesh.gridEy,mesh.gridEz]) # print(faceGrid.shape) ROI_large_BNW = np.array([-75,75,-75]) ROI_large_TSE = np.array([75,-75,75]) ROI_largeInds = Utils.ModelBuilder.getIndicesBlock(ROI_large_BNW,ROI_large_TSE,edgeGrid)[0] # print(ROI_largeInds.shape) ROI_small_BNW = np.array([-4,4,-4]) ROI_small_TSE = np.array([4,-4,4]) ROI_smallInds = Utils.ModelBuilder.getIndicesBlock(ROI_small_BNW,ROI_small_TSE,edgeGrid)[0] # print(ROI_smallInds.shape) ROIedgeInds = np.setdiff1d(ROI_largeInds,ROI_smallInds) # print(ROIedgeInds.shape) # print(len(ROI_largeInds) - len(ROI_smallInds)) self.survey = survey self.mesh = mesh self.sigma = sigma self.E_analytic = E_analytic self.J_analytic = J_analytic self.ROIedgeInds = ROIedgeInds
else: raise ValueError('Invalid component') if nSrc == 1: return A.flatten() return A if __name__ == '__main__': from SimPEG import Mesh import matplotlib.pyplot as plt cs = 20 ncx, ncy, ncz = 41, 41, 40 hx = np.ones(ncx)*cs hy = np.ones(ncy)*cs hz = np.ones(ncz)*cs mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC') srcLoc = np.r_[0., 0., 0.] Ax = MagneticLoopVectorPotential(srcLoc, mesh.gridEx, 'x', 200) Ay = MagneticLoopVectorPotential(srcLoc, mesh.gridEy, 'y', 200) Az = MagneticLoopVectorPotential(srcLoc, mesh.gridEz, 'z', 200) A = np.r_[Ax, Ay, Az] B0 = mesh.edgeCurl*A J0 = mesh.edgeCurl.T*B0 # mesh.plotImage(A, vType = 'Ex') # mesh.plotImage(A, vType = 'Ey') mesh.plotImage(B0, vType = 'Fx') mesh.plotImage(B0, vType = 'Fy') mesh.plotImage(B0, vType = 'Fz')
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]) wires = Maps.Wires(('eta', actmapeta.nP), ('taui', actmaptau.nP)) problem = SIP.Problem3D_N( mesh, sigma=sigma, etaMap=actmapeta*wires.eta, tauiMap=actmapeta*wires.taui ) 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): 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_CC( mesh, rho=1./sigma, etaMap=wires.eta, tauiMap=wires.taui ) 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 plotSecondarySource(self, primaryFields, saveFig=False): # get source term secondaryProblem = self.setupSecondaryProblem(mapping=self.mapping) secondaryProblem.solver = Solver self.primaryProblem.solver = Solver secondaryProblem.model = self.mtrue secondarySurvey = self.setupSecondarySurvey( self.primaryProblem, self.primarySurvey, self.primaryMap2meshs ) src = secondarySurvey.srcList[0] s_e = src.s_e(secondaryProblem, f=primaryFields) # Mesh to interpolate onto for stream plots cs = 5. csz = 0.5 xmin, xmax = -600., 600. ymin, ymax = -600., 600. zmin, zmax = -950.-csz/2., -950.+csz/2. ncx = np.ceil((xmax-xmin)/cs) ncy = np.ceil((ymax-ymin)/cs) ncz = np.ceil((zmax-zmin)/cs) meshs_plt = Mesh.TensorMesh( [[(cs, ncx)], [(cs, ncy)], [(cs, ncz)]], [xmin+(xmin+xmax)/2., ymin+(ymin+ymax)/2., zmin+(zmin+zmax)/2.] ) # Construct interpolation matrices Px = self.meshs.getInterpolationMat(meshs_plt.gridEx, locType='Ex') Py = self.meshs.getInterpolationMat(meshs_plt.gridEy, locType='Ey') Pz = self.meshs.getInterpolationMat(meshs_plt.gridEz, locType='Ez') P = sp.vstack([Px, Py, Pz]) # for regions outside of the anomalous block, the source current # density is identically zero. For plotting, we do not want to # interpolate into this region, so we build up masked arrays. maskme_ex = ( (self.meshs.gridEx[:, 0] <= self.block_x[0]) | (self.meshs.gridEx[:, 0] >= self.block_x[1]) | (self.meshs.gridEx[:, 1] <= self.block_y[0]) | (self.meshs.gridEx[:, 1] >= self.block_y[1]) ) maskme_ey = ( (self.meshs.gridEy[:, 0] <= self.block_x[0]) | (self.meshs.gridEy[:, 0] >= self.block_x[1]) | (self.meshs.gridEy[:, 1] <= self.block_y[0]) | (self.meshs.gridEy[:, 1] >= self.block_y[1]) ) maskme_ez = ( (self.meshs.gridEz[:, 0] <= self.block_x[0]) | (self.meshs.gridEz[:, 0] >= self.block_x[1]) | (self.meshs.gridEz[:, 1] <= self.block_y[0]) | (self.meshs.gridEz[:, 1] >= self.block_y[1]) ) maskme_e = np.hstack([maskme_ex, maskme_ey, maskme_ez]) # interpolate down a layer s_e_interp = s_e.real.copy() s_e_interp[maskme_e] = np.nan s_e_plt = P * s_e_interp # keep masked array for stream plots s_e_stream_cc = (meshs_plt.aveE2CCV * s_e_plt) # re-assign zero for amplitude of the real current density s_e_abs_cc = s_e_stream_cc.reshape(meshs_plt.nC, 3, order='F') s_e_abs_cc = np.sqrt((s_e_abs_cc**2.).sum(axis=1)) s_e_abs_cc[np.isnan(s_e_abs_cc)] = 0. s_e_stream_cc = np.ma.masked_where( np.isnan(s_e_stream_cc), s_e_stream_cc ) # plot fig, ax = plt.subplots(1, 1, figsize=(7.5, 6)) # f = meshs_plt.plotSlice( # np.ma.masked_where(maskme_e, s_e_plt.real), # normal='Z', # vType='CCv', # view='abs', # pcolorOpts={'cmap':plt.get_cmap('viridis')}, ax=ax # ) f = ax.pcolormesh( meshs_plt.vectorCCx, meshs_plt.vectorCCy, (s_e_abs_cc).reshape(meshs_plt.vnC[:2], order='F').T, cmap=plt.get_cmap('viridis') ) if saveFig is True: ax.streamplot( meshs_plt.vectorCCx, meshs_plt.vectorCCy, s_e_stream_cc[:meshs_plt.nC].reshape(meshs_plt.vnC[:2]), s_e_stream_cc[meshs_plt.nC:meshs_plt.nC*2].reshape( meshs_plt.vnC[:2]), density=1.5, color='k', arrowsize=8 ) elif saveFig is False: ax.streamplot( meshs_plt.vectorCCx, meshs_plt.vectorCCy, s_e_stream_cc[:meshs_plt.nC].reshape(meshs_plt.vnC[:2]), s_e_stream_cc[meshs_plt.nC:meshs_plt.nC*2].reshape( meshs_plt.vnC[:2] ), color='k', density=1.5 ) ax.set_xlabel('x (m)', fontsize=fontsize) ax.set_ylabel('y (m)', fontsize=fontsize) cb = plt.colorbar(f, label='real current density (A/m$^2$)') cb.formatter.set_powerlimits((0, 0)) cb.update_ticks() ax.axis('equal', adjustable='box') ax.axis([-600, 600, -600, 600]) ax.set_title('(a) -950m Depth Slice', fontsize=fontsize) # interact(plotMe, ind=[0, meshs_plt.vnC[2]-1]) if saveFig is True: fig.savefig('secondarySource', dpi=300) return ax
def dc_resistivity( log_sigma_background=1., # Conductivity of the background, S/m log_sigma_block=2, # Conductivity of the block, S/m plot_type='potential' # "conductivity", "potential", or "current" ): from pylab import rcParams rcParams['figure.figsize'] = 10, 10 # Define a unit-cell mesh mesh = Mesh.TensorMesh([100, 100]) # setup a mesh on which to solve # model parameters sigma_background = 10**log_sigma_background sigma_block = 10**log_sigma_block # add a block to our model x_block = np.r_[0.4, 0.6] y_block = np.r_[0.4, 0.6] # assign them on the mesh # create a physical property model sigma = sigma_background * np.ones(mesh.nC) block_indices = ((mesh.gridCC[:, 0] >= x_block[0]) & # left boundary (mesh.gridCC[:, 0] <= x_block[1]) & # right boundary (mesh.gridCC[:, 1] >= y_block[0]) & # bottom boundary (mesh.gridCC[:, 1] <= y_block[1])) # top boundary # add the block to the physical property model sigma[block_indices] = sigma_block # Define a source a_loc, b_loc = np.r_[0.2, 0.5], np.r_[0.8, 0.5] source_locs = [a_loc, b_loc] # locate it on the mesh source_loc_inds = Utils.closestPoints(mesh, source_locs) a_loc_mesh = mesh.gridCC[source_loc_inds[0], :] b_loc_mesh = mesh.gridCC[source_loc_inds[1], :] if plot_type == 'conductivity': plt.colorbar(mesh.plotImage(sigma)[0]) plt.plot(a_loc_mesh[0], a_loc_mesh[1], 'wv', markersize=8) plt.plot(b_loc_mesh[0], b_loc_mesh[1], 'w^', markersize=8) plt.title('electrical conductivity, $\sigma$') return # Assemble and solve the DC resistivity problem Div = mesh.faceDiv Sigma = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True) Vol = Utils.sdiag(mesh.vol) # assemble the system matrix A = Vol * Div * Sigma * Div.T * Vol # right hand side q = np.zeros(mesh.nC) q[source_loc_inds] = np.r_[+1, -1] # solve the DC resistivity problem Ainv = Solver(A) # create a matrix that behaves like A inverse phi = Ainv * q if plot_type == 'potential': plt.colorbar(mesh.plotImage(phi)[0]) plt.title('Electric Potential, $\phi$') return if plot_type == 'current': j = Sigma * mesh.faceDiv.T * Utils.sdiag(mesh.vol) * phi plt.colorbar( mesh.plotImage(j, vType='F', view='vec', streamOpts={'color': 'w'})[0]) plt.title('Current, $j$') return
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
padding_widths = cs * padding_fact**(np.arange(npad) + 1) return padding_widths.sum() # keep adding padding until we are beyond the desired extent padding_z = padding_extent(npad) while padding_z < domain_extent: npad += 1 padding_z = padding_extent(npad) print("{:1.0f} padding cells extends {:1.2e}m > {:1.2e}m " "(2 skin depths)".format(npad, padding_extent(npad), domain_extent)) ncz = np.ceil(core_extent / cs) # number of cells in the core domain hz = [(cs, npad, -1.3), (cs, ncz)] # define how to construct the cell widths mesh = Mesh.TensorMesh([hz], x0='N') # construct a 1D Tensor Mesh print("There are {:1.0f} cells in the mesh. The mest extends {:1.2e}m".format( ncz, mesh.hx.sum())) # plot the mesh fig, ax = plt.subplots(1, 1, figsize=(8, 3)) mesh.plotGrid(centers=True, faces=True, ax=ax) ax.legend(["centers", "faces"]) ax.grid(which="both", linewidth=0.5) ax.invert_xaxis() # so that the surface is on our left hand side ax.set_xlabel('z (m)') # Set up a model rho_target = 10. # resistivity in Ohm-m
def gettopoCC(mesh, actind, option="top"): """ Get topography from active indices of mesh. """ if mesh._meshType == "TENSOR": if mesh.dim == 3: mesh2D = Mesh.TensorMesh([mesh.hx, mesh.hy], mesh.x0[:2]) zc = mesh.gridCC[:, 2] ACTIND = actind.reshape((mesh.vnC[0] * mesh.vnC[1], mesh.vnC[2]), order='F') ZC = zc.reshape((mesh.vnC[0] * mesh.vnC[1], mesh.vnC[2]), order='F') topoCC = np.zeros(ZC.shape[0]) for i in range(ZC.shape[0]): ind = np.argmax(ZC[i, :][ACTIND[i, :]]) if option == "top": dz = mesh.hz[ACTIND[i, :]][ind] * 0.5 elif option == "center": dz = 0. else: raise Exception() topoCC[i] = (ZC[i, :][ACTIND[i, :]].max() + dz) return mesh2D, topoCC elif mesh.dim == 2: mesh1D = Mesh.TensorMesh([mesh.hx], [mesh.x0[0]]) yc = mesh.gridCC[:, 1] ACTIND = actind.reshape((mesh.vnC[0], mesh.vnC[1]), order='F') YC = yc.reshape((mesh.vnC[0], mesh.vnC[1]), order='F') topoCC = np.zeros(YC.shape[0]) for i in range(YC.shape[0]): ind = np.argmax(YC[i, :][ACTIND[i, :]]) if option == "top": dy = mesh.hy[ACTIND[i, :]][ind] * 0.5 elif option == "center": dy = 0. else: raise Exception() topoCC[i] = (YC[i, :][ACTIND[i, :]].max() + dy) return mesh1D, topoCC elif mesh._meshType == "TREE": if mesh.dim == 3: uniqXY = uniqueRows(mesh.gridCC[:, :2]) npts = uniqXY[0].shape[0] ZC = mesh.gridCC[:, 2] topoCC = np.zeros(npts) if option == "top": # TODO: this assume same hz, need to be modified dz = mesh.hz.min() * 0.5 elif option == "center": dz = 0. for i in range(npts): inds = uniqXY[2] == i actind_z = actind[inds] if actind_z.sum() > 0.: topoCC[i] = (ZC[inds][actind_z]).max() + dz else: topoCC[i] = (ZC[inds]).max() + dz return uniqXY[0], topoCC else: raise NotImplementedError( "gettopoCC is not implemented for Quad tree mesh")
def set_mesh_1d(hz): return Mesh.TensorMesh([hz], x0=[0])
def run(plotIt=True): # 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 = [ FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs ] surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prbFD.pair(surveyFD) std = 0.03 surveyFD.makeSyntheticData(mtrue, std) surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-5 # FDEM inversion np.random.seed(1) dmisfit = DataMisfit.l2_DataMisfit(surveyFD) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion Directives beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() directiveList = [beta, betaest, target] inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = np.log(np.ones(mtrue.size) * sig_half) reg.alpha_s = 5e-1 reg.alpha_x = 1. prbFD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptFD = inv.run(m0) # TDEM problem times = np.logspace(-4, np.log10(2e-3), 10) print('min diffusion distance ', 1.28 * np.sqrt(times.min() / (sig_half * mu_0)), 'max diffusion distance ', 1.28 * np.sqrt(times.max() / (sig_half * mu_0))) rx = TDEM.Rx.Point_b(rxlocs, times, 'z') src = TDEM.Src.MagDipole( [rx], waveform=TDEM.Src.StepOffWaveform(), loc=srcLoc # same src location as FDEM problem ) surveyTD = TDEM.Survey([src]) prbTD = TDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=Solver) prbTD.timeSteps = [(5e-5, 10), (1e-4, 10), (5e-4, 10)] prbTD.pair(surveyTD) std = 0.03 surveyTD.makeSyntheticData(mtrue, std) surveyTD.std = std surveyTD.eps = np.linalg.norm(surveyTD.dtrue) * 1e-5 # TDEM inversion dmisfit = DataMisfit.l2_DataMisfit(surveyTD) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = np.log(np.ones(mtrue.size) * sig_half) reg.alpha_s = 5e-1 reg.alpha_x = 1. prbTD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptTD = inv.run(m0) if plotIt: plt.figure(figsize=(10, 8)) ax0 = plt.subplot2grid((2, 2), (0, 0), rowspan=2) ax1 = plt.subplot2grid((2, 2), (0, 1)) ax2 = plt.subplot2grid((2, 2), (1, 1)) fs = 13 # fontsize matplotlib.rcParams['font.size'] = fs # Plot the model ax0.semilogx(sigma[active], mesh.vectorCCz[active], 'k-', lw=2) 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)
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 = [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 IRLS = Directives.Update_IRLS(f_min_change=1e-3, minGNiter=3) update_Jacobi = Directives.UpdatePreconditioner() self.inv = Inversion.BaseInversion( invProb, directiveList=[IRLS, betaest, update_Jacobi])
from SimPEG.EM.Static import DC import numpy as np import matplotlib.pyplot as plt ############################################################################### # Step 1 # ------ # # Generate mesh cs = 25. npad = 11 hx = [(cs, npad, -1.3), (cs, 41), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, 17), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy, hz], 'CCN') ############################################################################### # Step 2 # ------ # # Generating model and mapping (1D to 3D) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) siglay1 = 1. / (100.) siglay2 = 1. / (500.) sighalf = 1. / (100.) sigma = np.ones(mesh.nCz) * siglay1 sigma[mesh.vectorCCz <= -100.] = siglay2 sigma[mesh.vectorCCz < -150.] = sighalf mtrue = np.log(sigma)
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.RxTDEM(np.array([[rxOffset, 0., 30]]), np.logspace(-5, -3, 31), 'bz') src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([0., 0., 80])) survey = EM.TDEM.SurveyTDEM([src]) prb = EM.TDEM.ProblemTDEM_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 get_mesh(self): mesh = Mesh.TensorMesh([np.ones(20)]) mesh.setCellGradBC('dirichlet') return mesh
@property def Pafz(self): """ diagonal matrix that nulls out inactive z-faces to full modelling space (ie. nFz x nindActive_Fz ) :rtype: scipy.sparse.csr_matrix :return: active face-z diagonal matrix """ if getattr(self, "_Pafz", None) is None: if self.indActive is None: self._Pafz = Utils.speye(self.mesh.nFz) else: indActive_Fz = (self.mesh.aveFz2CC.T * self.indActive) >= 1 e = np.zeros(self.mesh.nFz) e[indActive_Fz] = 1.0 self._Pafz = Utils.sdiag(e) return self._Pafz if __name__ == "__main__": from SimPEG import Mesh, np mesh = Mesh.TensorMesh([10, 10]) L = np.ones(mesh.nC) src = StreamingCurrents([], L=L, mesh=mesh) thing = src.MfLiI if thing is not None: pass
def get_mesh(self): mesh = Mesh.TensorMesh([np.ones(8), np.ones(20), np.ones(10)]) mesh.setCellGradBC(['neumann', 'neumann', 'dirichlet']) return mesh
def set_mesh(self, topo=None, dx=None, dy=None, dz=None, n_spacing=None, corezlength=None, npad_x=7, npad_y=7, npad_z=7, pad_rate_x=1.3, pad_rate_y=1.3, pad_rate_z=1.3, ncell_per_dipole=4, mesh_type='TensorMesh', dimension=2, method='nearest' ): """ Set up a mesh for a given DC survey """ if mesh_type == 'TreeMesh': raise NotImplementedError() # 2D or 3D mesh if dimension in [2, 3]: if dimension == 2: z_ind = 1 else: z_ind = 2 a = abs(np.diff(np.sort(self.electrode_locations[:, 0]))).min() lineLength = abs( self.electrode_locations[:, 0].max() - self.electrode_locations[:, 0].min() ) dx_ideal = a/ncell_per_dipole if dx is None: dx = dx_ideal warnings.warn( "dx is set to {} m (samllest electrode spacing ({}) / {})".format(dx, a, ncell_per_dipole) ) if dz is None: dz = dx*0.5 warnings.warn( "dz ({} m) is set to dx ({} m) / {}".format(dz, dx, 2) ) x0 = self.electrode_locations[:, 0].min() if topo is None: locs = self.electrode_locations else: locs = np.vstack((topo, self.electrode_locations)) if dx > dx_ideal: # warnings.warn( # "Input dx ({}) is greater than expected \n We recommend using {:0.1e} m cells, that is, {} cells per {0.1e} m dipole length".format(dx, dx_ideal, ncell_per_dipole, a) # ) pass self.dx = dx self.dz = dz self.npad_x = npad_x self.npad_z = npad_z self.pad_rate_x = pad_rate_x self.pad_rate_z = pad_rate_z self.ncell_per_dipole = ncell_per_dipole zmax = locs[:, z_ind].max() zmin = locs[:, z_ind].min() # 3 cells each for buffer corexlength = lineLength + dx * 6 if corezlength is None: corezlength = self.grids[:, z_ind].max() ncx = np.round(corexlength/dx) ncz = np.round(corezlength/dz) hx = [ (dx, npad_x, -pad_rate_x), (dx, ncx), (dx, npad_x, pad_rate_x) ] hz = [(dz, npad_z, -pad_rate_z), (dz, ncz)] x0_mesh = -( (dx * pad_rate_x ** (np.arange(npad_x)+1)).sum() + dx * 3 - x0 ) z0_mesh = -((dz * pad_rate_z ** (np.arange(npad_z)+1)).sum() + dz * ncz) + zmax # For 2D mesh if dimension == 2: h = [hx, hz] x0_for_mesh = [x0_mesh, z0_mesh] self.xyzlim = np.vstack(( np.r_[x0, x0+lineLength], np.r_[zmax-corezlength, zmax] )) # For 3D mesh else: if dy is None: raise Exception("You must input dy (m)") self.dy = dy self.npad_y = npad_y self.pad_rate_y = pad_rate_y ylocs = np.unique(self.electrode_locations[:, 1]) ymin, ymax = ylocs.min(), ylocs.max() # 3 cells each for buffer in y-direction coreylength = ymax-ymin+dy*6 ncy = np.round(coreylength/dy) hy = [ (dy, npad_y, -pad_rate_y), (dy, ncy), (dy, npad_y, pad_rate_y) ] y0 = ylocs.min()-dy/2. y0_mesh = -( (dy * pad_rate_y ** (np.arange(npad_y)+1)).sum() + dy*3 - y0 ) h = [hx, hy, hz] x0_for_mesh = [x0_mesh, y0_mesh, z0_mesh] self.xyzlim = np.vstack(( np.r_[x0, x0+lineLength], np.r_[ymin-dy*3, ymax+dy*3], np.r_[zmax-corezlength, zmax] )) mesh = Mesh.TensorMesh(h, x0=x0_for_mesh) actind = Utils.surface2ind_topo(mesh, locs, method=method) else: raise NotImplementedError() return mesh, actind
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])
xlim = 150 # First we need to create a mesh and a model. # This is our mesh dx = 2. nC = 30 npad = 12 # Floor uncertainties for e3D inversion floor = 100 hxind = [(dx,npad,-1.3),(dx, 2*nC),(dx,npad,1.3)] hyind = [(dx, 2*nC)] hzind = [(dx, 3*nC)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CC0') mesh._x0[2] = -np.sum(mesh.hz[:(2*nC)]) # Set background conductivity model = np.ones(mesh.nC) * sig[0] # Sphere anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc, radi, mesh.gridCC) model[ind] = sig[1] # Create quick topo xtopo, ytopo = np.meshgrid(mesh.vectorNx,mesh.vectorNy) ztopo = np.zeros_like(xtopo) topo = np.c_[mkvc(xtopo),mkvc(ytopo),mkvc(ztopo)]
from matplotlib.path import Path import matplotlib.patches as patches from scipy.constants import epsilon_0 import copy from ipywidgets import interact, IntSlider, FloatSlider, FloatText, ToggleButtons from .Base import widgetify # Mesh, sigmaMap can be globals global npad = 15 growrate = 2. cs = 0.5 hx = [(cs, npad, -growrate), (cs, 200), (cs, npad, growrate)] hy = [(cs, npad, -growrate), (cs, 100)] mesh = Mesh.TensorMesh([hx, hy], "CN") idmap = Maps.IdentityMap(mesh) sigmaMap = idmap dx = 5 xr = np.arange(-40, 41, dx) dxr = np.diff(xr) xmin = -40. xmax = 40. ymin = -40. ymax = 5. xylim = np.c_[[xmin, ymin], [xmax, ymax]] indCC, meshcore = ExtractCoreMesh(xylim, mesh) indx = (mesh.gridFx[:,0]>=xmin) & (mesh.gridFx[:,0]<=xmax) \ & (mesh.gridFx[:,1]>=ymin) & (mesh.gridFx[:,1]<=ymax) indy = (mesh.gridFy[:,0]>=xmin) & (mesh.gridFy[:,0]<=xmax) \ & (mesh.gridFy[:,1]>=ymin) & (mesh.gridFy[:,1]<=ymax)
def simulate_dipole( self, component, target, inclination, declination, length, dx, moment, depth, profile, fixed_scale, show_halfwidth, ): self.component = component self.target = target self.inclination = inclination self.declination = declination self.length = length self.dx = dx self.moment = moment self.depth = depth self.profile = profile self.fixed_scale = fixed_scale self.show_halfwidth = show_halfwidth nT = 1e9 nx = ny = int(length / dx) hx = np.ones(nx) * dx hy = np.ones(ny) * dx self.mesh = Mesh.TensorMesh((hx, hy), "CC") z = np.r_[1.0] orientation = self.id_to_cartesian(inclination, declination) if self.target == "Dipole": md = em.static.MagneticDipoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (+)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = md.magnetic_flux_density(xyz) elif self.target == "Monopole (-)": md = em.static.MagneticPoleWholeSpace(location=np.r_[0, 0, -depth], orientation=orientation, moment=moment) xyz = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z) b_vec = -md.magnetic_flux_density(xyz) # Project to the direction of earth field if component == "Bt": rx_orientation = orientation.copy() elif component == "Bg": rx_orientation = orientation.copy() xyz_up = Utils.ndgrid(self.mesh.vectorCCx, self.mesh.vectorCCy, z + 1.0) b_vec -= md.magnetic_flux_density(xyz_up) elif component == "Bx": rx_orientation = self.id_to_cartesian(0, 0) elif component == "By": rx_orientation = self.id_to_cartesian(0, 90) elif component == "Bz": rx_orientation = self.id_to_cartesian(90, 0) self.data = self.dot_product(b_vec, rx_orientation) * nT # Compute profile if (profile == "North") or (profile == "None"): self.xy_profile = np.c_[np.zeros(self.mesh.nCx), self.mesh.vectorCCx] elif profile == "East": self.xy_profile = np.c_[self.mesh.vectorCCx, np.zeros(self.mesh.nCx)] self.inds_profile = Utils.closestPoints(self.mesh, self.xy_profile) self.data_profile = self.data[self.inds_profile]
def run(runIt=False, plotIt=True, saveIt=False, saveFig=False, cleanup=True): """ Run the bookpurnong 1D stitched RESOLVE inversions. :param bool runIt: re-run the inversions? Default downloads and plots saved results :param bool plotIt: show the plots? :param bool saveIt: save the re-inverted results? :param bool saveFig: save the figure :param bool cleanup: remove the downloaded results """ # download the data downloads, directory = download_and_unzip_data() # Load resolve data resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]), "r") river_path = resolve["river_path"].value # River path nSounding = resolve["data"].shape[0] # the # of soundings # Bird height from surface b_height_resolve = resolve["src_elevation"].value # fetch the frequencies we are considering cpi_inds = [0, 2, 6, 8, 10] # Indices for HCP in-phase cpq_inds = [1, 3, 7, 9, 11] # Indices for HCP quadrature frequency_cp = resolve["frequency_cp"].value # build a 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. # survey parameters rxOffset = 7.86 # tx-rx separation bp = -mu_0 / (4 * np.pi * rxOffset**3) # primary magnetic field # re-run the inversion if runIt: # set up the mappings - we are inverting for 1D log conductivity # below the earth's surface. actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap # build starting and reference model sig_half = 1e-1 sig_air = 1e-8 sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half m0 = np.log(1e-1) * np.ones(active.sum()) # starting model mref = np.log(1e-1) * np.ones(active.sum()) # reference model # initalize empty lists for storing inversion results mopt_re = [] # recovered model dpred_re = [] # predicted data dobs_re = [] # observed data # downsample the data for the inversion nskip = 40 # set up a noise model # 10% for the 3 lowest frequencies, 15% for the two highest std = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2) floor = abs(20 * bp * 1e-6) # floor of 20ppm # loop over the soundings and invert each for rxind in range(nSounding): # convert data from ppm to magnetic field (A/m^2) dobs = np.c_[resolve["data"][rxind, :][cpi_inds].astype(float), resolve["data"][rxind, :][cpq_inds]. astype(float)].flatten() * bp * 1e-6 # perform the inversion src_height = b_height_resolve[rxind].astype(float) mopt, dpred, dobs = resolve_1Dinversions(mesh, dobs, src_height, frequency_cp, m0, mref, mapping, std=std, floor=floor) # add results to our list mopt_re.append(mopt) dpred_re.append(dpred) dobs_re.append(dobs) # save results mopt_re = np.vstack(mopt_re) dpred_re = np.vstack(dpred_re) dobs_re = np.vstack(dobs_re) if saveIt: np.save("mopt_re_final", mopt_re) np.save("dobs_re_final", dobs_re) np.save("dpred_re_final", dpred_re) mopt_re = resolve["mopt"].value dobs_re = resolve["dobs"].value dpred_re = resolve["dpred"].value sigma = np.exp(mopt_re) indz = -7 # depth index # so that we can visually compare with literature (eg Viezzoli, 2010) cmap = "jet" # dummy figure for colobar fig = plt.figure() out = plt.scatter(np.ones(3), np.ones(3), c=np.linspace(-2, 1, 3), cmap=cmap) plt.close(fig) # plot from the paper fs = 13 # fontsize # matplotlib.rcParams['font.size'] = fs plt.figure(figsize=(13, 7)) ax0 = plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2) ax1 = plt.subplot2grid((2, 3), (0, 2)) ax2 = plt.subplot2grid((2, 3), (1, 2)) # titles of plots title = [("(a) Recovered model, %.1f m depth") % (-mesh.vectorCCz[active][indz]), "(b) Obs (Real 400 Hz)", "(c) Pred (Real 400 Hz)"] temp = sigma[:, indz] tree = cKDTree(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1]))) d, d_inds = tree.query(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])), k=20) w = 1. / (d + 100.)**2. w = Utils.sdiag(1. / np.sum(w, axis=1)) * (w) xy = resolve["xy"] temp = (temp.flatten()[d_inds] * w).sum(axis=1) Utils.plot2Ddata(xy, temp, ncontour=100, scale="log", dataloc=False, contourOpts={ "cmap": cmap, "vmin": -2, "vmax": 1. }, ax=ax0) ax0.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], 'k.', alpha=0.02, ms=1) cb = plt.colorbar(out, ax=ax0, ticks=np.linspace(-2, 1, 4), format="$10^{%.1f}$") cb.set_ticklabels(["0.01", "0.1", "1", "10"]) cb.set_label("Conductivity (S/m)") ax0.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5) # plot observed and predicted data freq_ind = 0 axs = [ax1, ax2] temp_dobs = dobs_re[:, freq_ind].copy() ax1.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5) out = Utils.plot2Ddata(resolve["xy"].value, temp_dobs / abs(bp) * 1e6, ncontour=100, scale="log", dataloc=False, ax=ax1, contourOpts={"cmap": "viridis"}) vmin, vmax = out[0].get_clim() cb = plt.colorbar(out[0], ticks=np.linspace(vmin, vmax, 3), ax=ax1, format="%.1e", fraction=0.046, pad=0.04) cb.set_label("Bz (ppm)") temp_dpred = dpred_re[:, freq_ind].copy() # temp_dpred[mask_:_data] = np.nan ax2.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5) Utils.plot2Ddata(resolve["xy"].value, temp_dpred / abs(bp) * 1e6, ncontour=100, scale="log", dataloc=False, contourOpts={ "vmin": vmin, "vmax": vmax, "cmap": "viridis" }, ax=ax2) cb = plt.colorbar(out[0], ticks=np.linspace(vmin, vmax, 3), ax=ax2, format="%.1e", fraction=0.046, pad=0.04) cb.set_label("Bz (ppm)") for i, ax in enumerate([ax0, ax1, ax2]): xticks = [460000, 463000] yticks = [6195000, 6198000, 6201000] xloc, yloc = 462100.0, 6196500.0 ax.set_xticks(xticks) ax.set_yticks(yticks) # ax.plot(xloc, yloc, 'wo') ax.plot(river_path[:, 0], river_path[:, 1], 'k', lw=0.5) ax.set_aspect("equal") ax.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], 'k.', alpha=0.02, ms=1) ax.set_yticklabels([str(f) for f in yticks]) ax.set_ylabel("Northing (m)") ax.set_xlabel("Easting (m)") ax.set_title(title[i]) plt.tight_layout() if plotIt: plt.show() if saveFig is True: fig.savefig("obspred_resolve.png", dpi=200) if cleanup: os.remove(downloads) shutil.rmtree(directory)