tilestep = 7 for tt in tiles[tilestep:2 * tilestep]: print('Tile ' + str(tt) + ' of ' + str(len(tiles))) midX = np.mean([X1[tt], X2[tt]]) midY = np.mean([Y1[tt], Y2[tt]]) # Create new mesh padx = np.r_[dx[0] * expf**(np.asarray(range(npadxy)) + 1)] pady = np.r_[dx[1] * expf**(np.asarray(range(npadxy)) + 1)] hx = np.r_[padx[::-1], core_x, padx] hy = np.r_[pady[::-1], core_y, pady] # hz = np.r_[padb*2.,[33,26],np.ones(25)*22,[18,15,12,10,8,7,6], np.ones(18)*5,5*expf**(np.asarray(range(2*npad)))] hz = mesh.hz mesh_t = Mesh.TensorMesh([hx, hy, hz], 'CC0') # mtemp._x0 = [x0[ii]-np.sum(padb), y0[ii]-np.sum(padb), mesh.x0[2]] mesh_t._x0 = (mesh_t.x0[0] + midX, mesh_t.x0[1] + midY, mesh.x0[2]) Mesh.TensorMesh.writeUBC( mesh_t, work_dir + out_dir + tile_dirl2 + "MAG_Tile" + str(tt) + ".msh") Mesh.TensorMesh.writeUBC( mesh_t, work_dir + out_dir + tile_dirlp + "MAG_Tile" + str(tt) + ".msh") # meshes.append(mtemp) # Grab the right data xlim = [mesh_t.vectorCCx[npadxy], mesh_t.vectorCCx[-npadxy]]
def getRHS(self): """ RHS for the DC problem q """ RHS = self.getSourceTerm() return RHS def getRHSDeriv(self, src, v, adjoint=False): """ Derivative of the right hand side with respect to the model """ # TODO: add qDeriv for RHS depending on m # qDeriv = src.evalDeriv(self, adjoint=adjoint) # return qDeriv return Zero() if __name__ == '__main__': cs = 12.5 hx = [(cs, 7, -1.3), (cs, 21), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 21), (cs, 7, 1.3)] hz = [(cs, 7, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN") sigma = np.ones(mesh.nC) prob = BaseIPProblem(mesh, sigma=sigma)
def plotCurrentDensity(mesh, fields_j, saveFig=False, figsize=(4, 5), fontsize=12, csx=5., csz=5., xmax=1000., zmin=0., zmax=-1200., real_or_imag='real', mirror=False, ax=None, fig=None, clim=None): csx, ncx = csx, np.ceil(xmax / csx) csz, ncz = csz, np.ceil((zmin - zmax) / csz) if mirror is True: xlim = [-xmax, xmax] x0 = [-xmax, -csx / 2., zmax] ncx *= 2. else: xlim = [0., xmax] x0 = [0, -csx / 2., zmax] ylim = [zmax, zmin] # define the tensor mesh meshcart = Mesh.TensorMesh([[(csx, ncx)], [(csx, 1)], [(csz, ncz)]], x0) projF = mesh.getInterpolationMatCartMesh(meshcart, 'F') jcart = projF * fields_j jcart = getattr(jcart, real_or_imag) if ax is None: fig, ax = plt.subplots(1, 1, figsize=figsize) if saveFig is True: # this looks obnoxious inline, but nice in the saved png f = meshcart.plotSlice(jcart, normal='Y', vType='F', view='vec', pcolorOpts={ 'norm': LogNorm(), 'cmap': plt.get_cmap('viridis') }, streamOpts={ 'arrowsize': 6, 'color': 'k' }, ax=ax) else: f = meshcart.plotSlice(jcart, normal='Y', vType='F', view='vec', pcolorOpts={ 'norm': LogNorm(), 'cmap': plt.get_cmap('viridis') }, ax=ax) plt.colorbar(f[0], label='{} current density (A/m$^2$)'.format(real_or_imag)) if clim is not None: f.set_clim(clim) ax.set_ylim(ylim) ax.set_xlim(xlim) # ax.set_title('Current Density') ax.set_xlabel('radius (m)', fontsize=fontsize) ax.set_ylabel('z (m)', fontsize=fontsize) if saveFig is True: fig.savefig('primaryCurrents', dpi=300, bbox_inches='tight') return ax
def test_ParametricSplineMap(self): M2 = Mesh.TensorMesh([np.ones(10), np.ones(10)], "CN") x = M2.vectorCCx mParamSpline = Maps.ParametricSplineMap(M2, x, normal='Y', order=1) self.assertTrue(mParamSpline.test()) self.assertTrue(mParamSpline.testVec())
import SimPEG.VRM as VRM import numpy as np from SimPEG import mkvc, Mesh, Maps import matplotlib.pyplot as plt import matplotlib as mpl ########################################################################## # Defining the mesh # ----------------- # cs, ncx, ncy, ncz, npad = 2., 35, 35, 20, 5 hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC') ########################################################################## # Defining the model # ------------------ # # Create xi model (amalgamated magnetic property). Here the model is made by # summing a set of 3D Gaussian distributions. And only active cells have a # model value. # topoCells = mesh.gridCC[:, 2] < 0. # Define topography xyzc = mesh.gridCC[topoCells, :] c = 2 * np.pi * 8**2 pc = np.r_[4e-4, 4e-4, 4e-4, 6e-4, 8e-4, 6e-4, 8e-4, 8e-4]
def run(plotIt=True): """ PF: Magnetic: Inversion Linear =============================== Create a synthetic block model and invert with a compact norm """ # 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 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.Wd = 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(norms=([0, 1, 1, 1]), eps=(5e-4, 5e-4), 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 * reg.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 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, 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. 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 # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.Wd = 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(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): 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') # 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] # 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 model = np.zeros(mesh.nC) # Change values in half the domain model[mesh.gridCC[:, 0] < 0] = 0.01 # Add a block in half-space model = Utils.ModelBuilder.addBlock(mesh.gridCC, model, np.r_[-10, -10, 20], np.r_[10, 10, 40], 0.05) model = Utils.mkvc(model) model = model[actv] # Create active map to go from reduce set to full actvMap = Maps.InjectActiveCells(mesh, actv, np.nan) # Create reduced identity map idenMap = Maps.IdentityMap(nP=len(actv)) # 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 # Plot the data rxLoc = survey.srcField.rxList[0].locs # Create a homogenous maps for the two domains domains = [mesh.gridCC[actv, 0] < 0, mesh.gridCC[actv, 0] >= 0] homogMap = Maps.SurjectUnits(domains) # Create a wire map for a second model space, voxel based wires = Maps.Wires(('h**o', len(domains)), ('hetero', len(actv))) # Create Sum map sumMap = Maps.SumMap([homogMap * wires.h**o, wires.hetero]) # Create the forward model operator prob = PF.Magnetics.MagneticIntegral(mesh, chiMap=sumMap, actInd=actv) # Pair the survey and problem survey.unpair() survey.pair(prob) # Make depth weighting wr = np.zeros(sumMap.shape[1]) # Take the cell number out of the scaling. # Want to keep high sens for large volumes scale = Utils.sdiag(np.r_[Utils.mkvc(1. / homogMap.P.sum(axis=0)), np.ones_like(actv)]) for ii in range(survey.nD): wr += ((prob.G[ii, :] * prob.chiMap.deriv(np.ones(sumMap.shape[1]) * 1e-4) * scale) / survey.std[ii])**2. # Scale the model spaces independently wr[wires.h**o.index] /= (np.max((wires.h**o * wr))) wr[wires.hetero.index] /= (np.max(wires.hetero * wr)) wr = wr**0.5 ## Create a regularization # For the homogeneous model regMesh = Mesh.TensorMesh([len(domains)]) reg_m1 = Regularization.Sparse(regMesh, mapping=wires.h**o) reg_m1.cell_weights = wires.h**o * wr reg_m1.norms = np.c_[0, 2, 2, 2] reg_m1.mref = np.zeros(sumMap.shape[1]) # Regularization for the voxel model reg_m2 = Regularization.Sparse(mesh, indActive=actv, mapping=wires.hetero) reg_m2.cell_weights = wires.hetero * wr reg_m2.norms = np.c_[0, 1, 1, 1] reg_m2.mref = np.zeros(sumMap.shape[1]) reg = reg_m1 + reg_m2 # 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, tolG=1e-3, eps=1e-6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt) betaest = Directives.BetaEstimate_ByEig() # 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-3, minGNiter=1) update_Jacobi = Directives.UpdatePreconditioner() inv = Inversion.BaseInversion(invProb, directiveList=[IRLS, betaest, update_Jacobi]) # Run the inversion m0 = np.ones(sumMap.shape[1]) * 1e-4 # Starting model prob.model = m0 mrecSum = inv.run(m0) if plotIt: mesh.plot_3d_slicer(actvMap * model, aspect="equal", zslice=30, pcolorOpts={"cmap": 'inferno_r'}, transparent='slider') mesh.plot_3d_slicer(actvMap * sumMap * mrecSum, aspect="equal", zslice=30, pcolorOpts={"cmap": 'inferno_r'}, transparent='slider')
rxLoc = survey.srcField.rxList[0].locs wr = np.zeros(nC) for ii in range(survey.nD): wr += ((prob.F[ii, :] * prob.chiMap.deriv(m0)) / survey.std[ii])**2. wr = (wr / np.max(wr)) wr = wr**0.5 Mesh.TensorMesh.writeModelUBC(mesh, work_dir + out_dir + 'SensWeights.sus', actvMap * (homogMap.P * wr)) # wr = PF.Magnetics.get_dist_wgt(mesh, rxLoc, actv, 3, 1) # Create reduced identity map 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 = np.zeros(nC) # Data misfit function dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / survey.std # Add directives to the inversion
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 readUBC_DC2DMesh(fileName): """ Read UBC GIF 2DTensor mesh and generate 2D Tensor mesh in simpeg Input: :param fileName, path to the UBC GIF mesh file Output: :param SimPEG TensorMesh 2D object :return Created on Thu Nov 12 13:14:10 2015 @author: dominiquef """ from SimPEG import np # Open file fopen = open(fileName,'r') # Read down the file and unpack dx vector def unpackdx(fid,nrows): for ii in range(nrows): line = fid.readline() var = np.array(line.split(),dtype=float) if ii==0: x0= var[0] xvec = np.ones(int(var[2])) * (var[1] - var[0]) / int(var[2]) xend = var[1] else: xvec = np.hstack((xvec,np.ones(int(var[1])) * (var[0] - xend) / int(var[1]))) xend = var[0] return x0, xvec #%% Start with dx block # First line specifies the number of rows for x-cells line = fopen.readline() nl = np.array(line.split(),dtype=float) [x0, dx] = unpackdx(fopen,nl) #%% Move down the file until reaching the z-block line = fopen.readline() if not line: line = fopen.readline() #%% End with dz block # First line specifies the number of rows for z-cells line = fopen.readline() nl = np.array(line.split(),dtype=float) [z0, dz] = unpackdx(fopen,nl) # Flip z0 to be the bottom of the mesh for SimPEG z0 = z0 - sum(dz) dz = dz[::-1] #%% Make the mesh using SimPEG from SimPEG import Mesh tensMsh = Mesh.TensorMesh([dx,dz],(x0, z0)) return tensMsh
def run(plotIt=True): M = Mesh.TensorMesh([np.ones(40)], x0='N') M.setCellGradBC('dirichlet') # We will use the haverkamp empirical model with parameters from Celia1990 k_fun, theta_fun = Richards.Empirical.haverkamp(M, A=1.1750e+06, gamma=4.74, alpha=1.6110e+06, theta_s=0.287, theta_r=0.075, beta=3.96) # Here we are making saturated hydraulic conductivity # an exponential mapping to the model (defined below) k_fun.KsMap = Maps.ExpMap(nP=M.nC) # Setup the boundary and initial conditions bc = np.array([-61.5, -20.7]) h = np.zeros(M.nC) + bc[0] prob = Richards.RichardsProblem(M, hydraulic_conductivity=k_fun, water_retention=theta_fun, boundary_conditions=bc, initial_conditions=h, do_newton=False, method='mixed', debug=False) prob.timeSteps = [(5, 25, 1.1), (60, 40)] # Create the survey locs = -np.arange(2, 38, 4.) times = np.arange(30, prob.timeMesh.vectorCCx[-1], 60) rxSat = Richards.SaturationRx(locs, times) survey = Richards.RichardsSurvey([rxSat]) survey.pair(prob) # Create a simple model for Ks Ks = 1e-3 mtrue = np.ones(M.nC) * np.log(Ks) mtrue[15:20] = np.log(5e-2) mtrue[20:35] = np.log(3e-3) mtrue[35:40] = np.log(1e-2) # Create some synthetic data and fields Hs = prob.fields(mtrue) data = survey.makeSyntheticData(mtrue, std=0, f=Hs, force=True) if plotIt: plt.figure(figsize=(14, 9)) plt.subplot(221) plt.plot(np.log10(np.exp(mtrue)), M.gridCC) plt.title('(a) True model and data locations') plt.ylabel('Depth, cm') plt.xlabel('Hydraulic conductivity, $log_{10}(K_s)$') plt.plot([-3.25] * len(locs), locs, 'ro') plt.legend(('True model', 'Data locations')) plt.subplot(222) plt.plot(times / 60, data.reshape((-1, len(locs)))) plt.title('(b) True data over time at all depths') plt.xlabel('Time, minutes') plt.ylabel('Saturation') ax = plt.subplot(212) mesh2d = Mesh.TensorMesh([prob.timeMesh.hx / 60, prob.mesh.hx], '0N') sats = [theta_fun(_) for _ in Hs] clr = mesh2d.plotImage(np.c_[sats][1:, :], ax=ax) cmap0 = matplotlib.cm.RdYlBu_r clr[0].set_cmap(cmap0) c = plt.colorbar(clr[0]) c.set_label('Saturation $\\theta$') plt.xlabel('Time, minutes') plt.ylabel('Depth, cm') plt.title('(c) Saturation over time') plt.tight_layout()
def getDiffOpRot(mesh, psi, theta, phi, vec, forward=True): hz = np.kron(mesh.hz, np.kron(np.ones(mesh.vnC[1]), np.ones(mesh.vnC[0]))) hy = np.kron(np.ones(mesh.vnC[2]), np.kron(mesh.hy, np.ones(mesh.vnC[0]))) hx = np.kron(np.ones(mesh.vnC[2]), np.kron(np.ones(mesh.vnC[1]), mesh.hx)) unitMesh = Mesh.TensorMesh([np.ones(3), np.ones(3), np.ones(3)], x0='CCC') stencil = [] for ii in range(unitMesh.nC): stencil += [ np.kron(np.r_[-1, 1], [0.5, 0.5, 0.5]).reshape( (2, 3)) + np.kron(np.ones(2), unitMesh.gridCC[ii, :]).reshape( (2, 3)) ] if isinstance(theta, float): theta = np.ones(mesh.nC) * theta if isinstance(phi, float): phi = np.ones(mesh.nC) * phi if isinstance(psi, float): psi = np.ones(mesh.nC) * psi if forward: ind = 1 else: ind = -1 if vec == 'X': px = np.kron(np.ones(mesh.nC), np.c_[ind, 0, 0]) theta = np.arctan2((np.sin(theta) / hz), (np.cos(theta) / hx)) phi = np.arctan2((np.sin(phi) / hy), (np.cos(phi) / hx)) psi = np.arctan2((np.sin(psi) / hz), (np.cos(psi) / hy)) elif vec == 'Y': px = np.kron(np.ones(mesh.nC), np.c_[0, ind, 0]) theta = np.arctan2((np.sin(theta) / hz), (np.cos(theta) / hx)) phi = np.arctan2((np.sin(phi) / hx), (np.cos(phi) / hy)) psi = np.arctan2((np.sin(psi) / hz), (np.cos(psi) / hy)) else: px = np.kron(np.ones(mesh.nC), np.c_[0, 0, ind]) theta = np.arctan2((np.sin(theta) / hx), (np.cos(theta) / hz)) phi = np.arctan2((np.sin(phi) / hy), (np.cos(phi) / hx)) psi = np.arctan2((np.sin(psi) / hy), (np.cos(psi) / hz)) # v = np.ones((mesh.nC,27)) # for ii in range(mesh.nC): # S = Utils.sdiag(mkvc(np.c_[1/ratiox**0.5, 1/ratioy**0.5, 1/ratioz**0.5])) # Create sparse rotation operators rxa = mkvc(np.c_[np.ones(mesh.nC), np.cos(psi), np.cos(psi)].T) rxb = mkvc(np.c_[np.zeros(mesh.nC), np.sin(psi), np.zeros(mesh.nC)].T) rxc = mkvc(np.c_[np.zeros(mesh.nC), -np.sin(psi), np.zeros(mesh.nC)].T) Rx = sp.sparse.diags([rxb[:-1], rxa, rxc[:-1]], [-1, 0, 1]) rya = mkvc(np.c_[np.cos(theta), np.ones(mesh.nC), np.cos(theta)].T) ryb = mkvc(np.c_[-np.sin(theta), np.zeros(mesh.nC), np.zeros(mesh.nC)].T) ryc = mkvc(np.c_[np.sin(theta), np.zeros(mesh.nC), np.zeros(mesh.nC)].T) Ry = sp.sparse.diags([ryb[:-2], rya, ryc[:-2]], [-2, 0, 2]) rza = mkvc(np.c_[np.cos(phi), np.cos(phi), np.ones(mesh.nC)].T) rzb = mkvc(np.c_[np.sin(phi), np.zeros(mesh.nC), np.zeros(mesh.nC)].T) rzc = mkvc(np.c_[-np.sin(phi), np.zeros(mesh.nC), np.zeros(mesh.nC)].T) Rz = sp.sparse.diags([rzb[:-1], rza, rzc[:-1]], [-1, 0, 1]) # Rotate all cell vectors rx = (Rz * (Ry * (Rx * px.T))).reshape((mesh.nC, 3)) # Move the bottom-SW and top-NE nodes nBSW = np.kron(stencil[13][0], np.ones((mesh.nC, 1))) + rx nTNE = np.kron(stencil[13][1], np.ones((mesh.nC, 1))) + rx # Compute fractional volumes with base stencil V = [] for s in stencil: sBSW = np.kron(s[0], np.ones((mesh.nC, 1))) sTNE = np.kron(s[1], np.ones((mesh.nC, 1))) V += [(np.max([ np.min([sTNE[:, 0], nTNE[:, 0]], axis=0) - np.max([sBSW[:, 0], nBSW[:, 0]], axis=0), np.zeros(mesh.nC) ], axis=0) * np.max([ np.min([sTNE[:, 1], nTNE[:, 1]], axis=0) - np.max([sBSW[:, 1], nBSW[:, 1]], axis=0), np.zeros(mesh.nC) ], axis=0) * np.max([ np.min([sTNE[:, 2], nTNE[:, 2]], axis=0) - np.max([sBSW[:, 2], nBSW[:, 2]], axis=0), np.zeros(mesh.nC) ], axis=0))] count = -1 Gx = speye(mesh.nC) for ii in range(3): flagz = [0, 0, 0] flagz[ii] = 1 for jj in range(3): flagy = [0, 0, 0] flagy[jj] = 1 for kk in range(3): flagx = [0, 0, 0] flagx[kk] = 1 count += 1 Gx -= sdiag(np.ones(mesh.nC) * V[count]) * kron3( ddx(mesh.nCz, flagz), ddx(mesh.nCy, flagy), ddx(mesh.nCx, flagx)) return Gx, rx
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') active = mesh.vectorCCz < 0. layer = (mesh.vectorCCz < 0.) & (mesh.vectorCCz >= -100.) actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap sig_half = 2e-3 sig_air = 1e-8 sig_layer = 1e-3 sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half sigma[layer] = sig_layer mtrue = np.log(sigma[active]) rxOffset = 1e-3 rx = EM.TDEM.Rx.Point_dbdt(np.array([[rxOffset, 0., 30]]), np.logspace(-5, -3, 31), 'z') src = EM.TDEM.Src.MagDipole([rx], loc=np.array([0., 0., 80])) survey = EM.TDEM.Survey([src]) prb = EM.TDEM.Problem3D_e(mesh, sigmaMap=mapping) prb.Solver = SolverLU prb.timeSteps = [(1e-06, 20), (1e-05, 20), (0.0001, 20)] prb.pair(survey) # create observed data std = 0.05 survey.dobs = survey.makeSyntheticData(mtrue, std) survey.std = std survey.eps = 1e-5 * np.linalg.norm(survey.dobs) dmisfit = DataMisfit.l2_DataMisfit(survey) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Tikhonov(regMesh, alpha_s=1e-2, alpha_x=1.) opt = Optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Create an inversion object beta = Directives.BetaSchedule(coolingFactor=5, coolingRate=2) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest]) m0 = np.log(np.ones(mtrue.size) * sig_half) prb.counter = opt.counter = Utils.Counter() opt.remember('xc') mopt = inv.run(m0) if plotIt: fig, ax = plt.subplots(1, 2, figsize=(10, 6)) ax[0].loglog(rx.times, survey.dtrue, 'b.-') ax[0].loglog(rx.times, survey.dobs, 'r.-') ax[0].legend(('Noisefree', '$d^{obs}$'), fontsize=16) ax[0].set_xlabel('Time (s)', fontsize=14) ax[0].set_ylabel('$B_z$ (T)', fontsize=16) ax[0].set_xlabel('Time (s)', fontsize=14) ax[0].grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.semilogx(sigma[active], mesh.vectorCCz[active]) plt.semilogx(np.exp(mopt), mesh.vectorCCz[active]) ax[1].set_ylim(-600, 0) ax[1].set_xlim(1e-4, 1e-2) ax[1].set_xlabel('Conductivity (S/m)', fontsize=14) ax[1].set_ylabel('Depth (m)', fontsize=14) ax[1].grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'])
def run_simulation(fname="tdem_gs_half.h5", sigma_block=0.01, sigma_halfspace=0.01): from SimPEG.EM import TDEM, Analytics, mu_0 import numpy as np from SimPEG import Mesh, Maps, Utils, EM, Survey from pymatsolver import Pardiso cs = 20 ncx, ncy, ncz = 20, 20, 20 npad = 10 hx = [(cs, npad, -1.5), (cs, ncx), (cs, npad, 1.5)] hy = [(cs, npad, -1.5), (cs, ncy), (cs, npad, 1.5)] hz = [(cs, npad, -1.5), (cs, ncz), (cs, npad, 1.5)] mesh = Mesh.TensorMesh([hx, hy, hz], "CCC") sigma = np.ones(mesh.nC) * sigma_halfspace blk_ind = Utils.ModelBuilder.getIndicesBlock(np.r_[-40, -40, -160], np.r_[40, 40, -80], mesh.gridCC) sigma[mesh.gridCC[:, 2] > 0.0] = 1e-8 sigma[blk_ind] = sigma_block xmin, xmax = -200.0, 200.0 ymin, ymax = -200.0, 200.0 x = mesh.vectorCCx[np.logical_and(mesh.vectorCCx > xmin, mesh.vectorCCx < xmax)] y = mesh.vectorCCy[np.logical_and(mesh.vectorCCy > ymin, mesh.vectorCCy < ymax)] xyz = Utils.ndgrid(x, y, np.r_[-1.0]) px = np.r_[-200.0, 200.0] py = np.r_[0.0, 0.0] pz = np.r_[0.0, 0.0] srcLoc = np.c_[px, py, pz] from scipy.interpolate import interp1d prb = TDEM.Problem3D_b(mesh, sigma=sigma, verbose=True) prb.Solver = Pardiso prb.solverOpts = {"is_symmetric": False} prb.timeSteps = [(1e-3, 10), (2e-5, 10), (1e-4, 10), (5e-4, 10), (1e-3, 10)] t0 = 0.01 + 1e-4 out = EM.Utils.VTEMFun(prb.times, 0.01, t0, 200) wavefun = interp1d(prb.times, out) waveform = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun) input_currents = wavefun(prb.times) times = np.logspace(-4, -2, 21) rx_ex = TDEM.Rx.Point_e(xyz, times + t0, orientation="x") rx_ey = TDEM.Rx.Point_e(xyz, times + t0, orientation="y") rx_by = TDEM.Rx.Point_e(xyz, times + t0, orientation="y") rxList = [rx_ex, rx_ey, rx_by] src = TDEM.Src.LineCurrent(rxList, loc=srcLoc, waveform=waveform) survey = TDEM.Survey([src]) survey.pair(prb) f = prb.fields(sigma) xyzlim = np.array([[xmin, xmax], [ymin, ymax], [-400, 0.0]]) actinds, meshCore = Utils.ExtractCoreMesh(xyzlim, mesh) Pex = mesh.getInterpolationMat(meshCore.gridCC, locType="Ex") Pey = mesh.getInterpolationMat(meshCore.gridCC, locType="Ey") Pez = mesh.getInterpolationMat(meshCore.gridCC, locType="Ez") Pfx = mesh.getInterpolationMat(meshCore.gridCC, locType="Fx") Pfy = mesh.getInterpolationMat(meshCore.gridCC, locType="Fy") Pfz = mesh.getInterpolationMat(meshCore.gridCC, locType="Fz") sigma_core = sigma[actinds] def getEBJcore(src0): B0 = np.r_[Pfx * f[src0, "b"], Pfy * f[src0, "b"], Pfz * f[src0, "b"]] E0 = np.r_[Pex * f[src0, "e"], Pey * f[src0, "e"], Pez * f[src0, "e"]] J0 = Utils.sdiag(np.r_[sigma_core, sigma_core, sigma_core]) * E0 return E0, B0, J0 E, B, J = getEBJcore(src) tdem_gs = { "E": E, "B": B, "J": J, "sigma": sigma_core, "mesh": meshCore.serialize(), "time": prb.times - t0, "input_currents": input_currents, } dd.io.save(fname, tdem_gs)
pad_x_factor = 1.3 pad_y_factor = 1.3 pad_z_factor = 1.3 # ============================================================================= # # ============================================================================= ### ( initial width, number of cells, increase by factor) ### (pad, center, pad) hx_ind = [(dx, pad_x, -pad_x_factor), (dx, nx), (dx, pad_x, pad_x_factor)] hy_ind = [(dy, pad_y, -pad_y_factor), (dy, ny), (dy, pad_y, pad_y_factor)] hz_ind = [(dz, pad_z, -pad_z_factor), (dz, nz), (3.5, 1), (2, 5)] ### make a mesh mesh = Mesh.TensorMesh([hx_ind, hy_ind, hz_ind], 'CCC') # Get index of the center mid_x = int(mesh.nCx/2) mid_y = 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 active_cells = Utils.surface2ind_topo(mesh, topo, 'N') active_cells = np.where(active_cells)[0]
def halfSpaceProblemAnaDiff(meshType, srctype="MagDipole", sig_half=1e-2, rxOffset=50., bounds=None, plotIt=False, rxType='bz'): if bounds is None: bounds = [1e-5, 1e-3] if meshType == 'CYL': cs, ncx, ncz, npad = 15., 30, 10, 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') elif meshType == 'TENSOR': cs, nc, npad = 20., 13, 5 hx = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, nc), (cs, npad, 1.3)] mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC') active = mesh.vectorCCz < 0. actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap prb = EM.TDEM.Problem3D_b(mesh, sigmaMap=mapping) prb.Solver = Solver prb.timeSteps = [(1e-3, 5), (1e-4, 5), (5e-5, 10), (5e-5, 10), (1e-4, 10)] out = EM.Utils.VTEMFun(prb.times, 0.00595, 0.006, 100) wavefun = interp1d(prb.times, out) t0 = 0.006 waveform = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun) rx = getattr(EM.TDEM.Rx, 'Point_{}'.format(rxType[:-1]))(np.array([[rxOffset, 0., 0.]]), np.logspace(-4, -3, 31) + t0, rxType[-1]) if srctype == "MagDipole": src = EM.TDEM.Src.MagDipole([rx], waveform=waveform, loc=np.array([0, 0., 0.])) elif srctype == "CircularLoop": src = EM.TDEM.Src.CircularLoop([rx], waveform=waveform, loc=np.array([0., 0., 0.]), radius=13.) survey = EM.TDEM.Survey([src]) prb.pair(survey) sigma = np.ones(mesh.nCz) * 1e-8 sigma[active] = sig_half sigma = np.log(sigma[active]) if srctype == "MagDipole": bz_ana = mu_0 * EM.Analytics.hzAnalyticDipoleT(rx.locs[0][0] + 1e-3, rx.times - t0, sig_half) elif srctype == "CircularLoop": bz_ana = mu_0 * EM.Analytics.hzAnalyticCentLoopT( 13, rx.times - t0, sig_half) bz_calc = survey.dpred(sigma) ind = np.logical_and(rx.times - t0 > bounds[0], rx.times - t0 < bounds[1]) log10diff = (np.linalg.norm( np.log10(np.abs(bz_calc[ind])) - np.log10(np.abs(bz_ana[ind]))) / np.linalg.norm(np.log10(np.abs(bz_ana[ind])))) print(' |bz_ana| = {ana} |bz_num| = {num} |bz_ana-bz_num| = {diff}'.format( ana=np.linalg.norm(bz_ana), num=np.linalg.norm(bz_calc), diff=np.linalg.norm(bz_ana - bz_calc))) print('Difference: {}'.format(log10diff)) if plotIt is True: plt.loglog(rx.times[bz_calc > 0] - t0, bz_calc[bz_calc > 0], 'r', rx.times[bz_calc < 0] - t0, -bz_calc[bz_calc < 0], 'r--') plt.loglog(rx.times - t0, abs(bz_ana), 'b*') plt.title('sig_half = {:e}'.format(sig_half)) plt.show() return log10diff
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() 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(plotIt=True): """ EM: TDEM: 1D: Inversion with VTEM waveform ========================================== Here we will create and run a TDEM 1D inversion, with VTEM waveform of which initial condition is zero, but have some on- and off-time. """ cs, ncx, ncz, npad = 5., 25, 24, 15 hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') active = mesh.vectorCCz < 0. layer = (mesh.vectorCCz < -50.) & (mesh.vectorCCz >= -150.) actMap = Maps.InjectActiveCells(mesh, active, np.log(1e-8), nC=mesh.nCz) mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap sig_half = 1e-3 sig_air = 1e-8 sig_layer = 1e-2 sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half sigma[layer] = sig_layer mtrue = np.log(sigma[active]) x = np.r_[30, 50, 70, 90] rxloc = np.c_[x, x * 0., np.zeros_like(x)] prb = EM.TDEM.Problem3D_b(mesh, sigmaMap=mapping) prb.Solver = Solver prb.timeSteps = [(1e-3, 5), (1e-4, 5), (5e-5, 10), (5e-5, 5), (1e-4, 10), (5e-4, 10)] # Use VTEM waveform out = EM.Utils.VTEMFun(prb.times, 0.00595, 0.006, 100) # Forming function handle for waveform using 1D linear interpolation wavefun = interp1d(prb.times, out) t0 = 0.006 waveform = EM.TDEM.Src.RawWaveform(offTime=t0, waveFct=wavefun) rx = EM.TDEM.Rx.Point_dbdt(rxloc, np.logspace(-4, -2.5, 11) + t0, 'z') src = EM.TDEM.Src.CircularLoop([rx], waveform=waveform, loc=np.array([0., 0., 0.]), radius=10.) survey = EM.TDEM.Survey([src]) prb.pair(survey) # create observed data std = 0.02 survey.dobs = survey.makeSyntheticData(mtrue, std) # dobs = survey.dpred(mtrue) survey.std = std survey.eps = 1e-11 dmisfit = DataMisfit.l2_DataMisfit(survey) regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIter=5, LSshorten=0.5) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) target = Directives.TargetMisfit() # Create an inversion object beta = Directives.BetaSchedule(coolingFactor=1., coolingRate=2.) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) invProb.beta = 1e2 inv = Inversion.BaseInversion(invProb, directiveList=[beta, target]) m0 = np.log(np.ones(mtrue.size) * sig_half) prb.counter = opt.counter = Utils.Counter() opt.remember('xc') mopt = inv.run(m0) if plotIt: fig, ax = plt.subplots(1, 2, figsize=(10, 6)) Dobs = survey.dobs.reshape((len(rx.times), len(x))) Dpred = invProb.dpred.reshape((len(rx.times), len(x))) for i in range(len(x)): ax[0].loglog(rx.times - t0, -Dobs[:, i].flatten(), 'k') ax[0].loglog(rx.times - t0, -Dpred[:, i].flatten(), 'k.') if i == 0: ax[0].legend(('$d^{obs}$', '$d^{pred}$'), fontsize=16) ax[0].set_xlabel('Time (s)', fontsize=14) ax[0].set_ylabel('$db_z / dt$ (nT/s)', fontsize=16) ax[0].set_xlabel('Time (s)', fontsize=14) ax[0].grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.semilogx(sigma[active], mesh.vectorCCz[active]) plt.semilogx(np.exp(mopt), mesh.vectorCCz[active]) ax[1].set_ylim(-600, 0) ax[1].set_xlim(1e-4, 1e-1) ax[1].set_xlabel('Conductivity (S/m)', fontsize=14) ax[1].set_ylabel('Depth (m)', fontsize=14) ax[1].grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5) plt.legend(['$\sigma_{true}$', '$\sigma_{pred}$'])
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
def test_ParametricPolyMap(self): M2 = Mesh.TensorMesh([np.ones(10), np.ones(10)], "CN") mParamPoly = Maps.ParametricPolyMap(M2, 2, logSigma=True, normal='Y') self.assertTrue(mParamPoly.test(m=np.r_[1., 1., 0., 0., 0.])) self.assertTrue(mParamPoly.testVec(m=np.r_[1., 1., 0., 0., 0.]))
def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False): cs = 10. ncx, ncy, ncz = 0, 0, 0 npad = 8 hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.TensorMesh([hx, hy, hz], ['C', 'C', 'C']) if useMu is True: mapping = [('sigma', Maps.ExpMap(mesh)), ('mu', Maps.IdentityMap(mesh))] else: mapping = Maps.ExpMap(mesh) x = np.array( [np.linspace(-5. * cs, -2. * cs, 3), np.linspace(5. * cs, 2. * cs, 3)] ) + cs / 4. #don't sample right by the source, slightly off alignment from either staggered grid XYZ = Utils.ndgrid(x, x, np.linspace(-2. * cs, 2. * cs, 5)) Rx0 = getattr(EM.FDEM.Rx, 'Point_' + comp[0]) if comp[2] == 'r': real_or_imag = 'real' elif comp[2] == 'i': real_or_imag = 'imag' rx0 = Rx0(XYZ, comp[1], 'imag') Src = [] for SrcType in SrcList: if SrcType is 'MagDipole': Src.append( EM.FDEM.Src.MagDipole([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'MagDipole_Bfield': Src.append( EM.FDEM.Src.MagDipole_Bfield([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'CircularLoop': Src.append( EM.FDEM.Src.CircularLoop([rx0], freq=freq, loc=np.r_[0., 0., 0.])) elif SrcType is 'RawVec': if fdemType is 'e' or fdemType is 'b': S_m = np.zeros(mesh.nF) S_e = np.zeros(mesh.nE) S_m[Utils.closestPoints(mesh, [0., 0., 0.], 'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 S_e[Utils.closestPoints(mesh, [0., 0., 0.], 'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 Src.append( EM.FDEM.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct() * S_e)) elif fdemType is 'h' or fdemType is 'j': S_m = np.zeros(mesh.nE) S_e = np.zeros(mesh.nF) S_m[Utils.closestPoints(mesh, [0., 0., 0.], 'Ez') + np.sum(mesh.vnE[:1])] = 1e-3 S_e[Utils.closestPoints(mesh, [0., 0., 0.], 'Fz') + np.sum(mesh.vnF[:1])] = 1e-3 Src.append( EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct() * S_m, S_e)) if verbose: print(' Fetching {0!s} problem'.format((fdemType))) if fdemType == 'e': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_e(mesh, mapping=mapping) elif fdemType == 'b': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping) elif fdemType == 'j': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_j(mesh, mapping=mapping) elif fdemType == 'h': survey = EM.FDEM.Survey(Src) prb = EM.FDEM.Problem3D_h(mesh, mapping=mapping) else: raise NotImplementedError() prb.pair(survey) try: from pymatsolver import PardisoSolver prb.Solver = PardisoSolver except ImportError: prb.Solver = SolverLU # prb.solverOpts = dict(check_accuracy=True) return prb
def run(plotIt=True): """ 1D FDEM Mu Inversion ==================== 1D inversion of Magnetic Susceptibility from FDEM data assuming a fixed electrical conductivity """ # Set up cylindrically symmeric mesh cs, ncx, ncz, npad = 10., 15, 25, 13 # padded cyl mesh hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') # Geologic Parameters model layerz = np.r_[-100., -50.] layer = (mesh.vectorCCz >= layerz[0]) & (mesh.vectorCCz <= layerz[1]) active = mesh.vectorCCz < 0. # Electrical Conductivity sig_half = 1e-2 # Half-space conductivity sig_air = 1e-8 # Air conductivity sig_layer = 1e-2 # Layer conductivity sigma = np.ones(mesh.nCz) * sig_air sigma[active] = sig_half sigma[layer] = sig_layer # mur - relative magnetic permeability mur_half = 1. mur_air = 1. mur_layer = 2. mur = np.ones(mesh.nCz) * mur_air mur[active] = mur_half mur[layer] = mur_layer mtrue = mur[active] # Maps actMap = Maps.InjectActiveCells(mesh, active, mur_air, nC=mesh.nCz) surj1Dmap = Maps.SurjectVertical1D(mesh) murMap = Maps.MuRelative(mesh) # Mapping muMap = murMap * surj1Dmap * actMap # ----- FDEM problem & survey ----- rxlocs = Utils.ndgrid([np.r_[10.], np.r_[0], np.r_[30.]]) bzr = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'real') # bzi = FDEM.Rx.Point_bSecondary(rxlocs, 'z', 'imag') freqs = np.linspace(2000, 10000, 10) #np.logspace(3, 4, 10) srcLoc = np.array([0., 0., 30.]) print('min skin depth = ', 500. / np.sqrt(freqs.max() * sig_half), 'max skin depth = ', 500. / np.sqrt(freqs.min() * sig_half)) print('max x ', mesh.vectorCCx.max(), 'min z ', mesh.vectorCCz.min(), 'max z ', mesh.vectorCCz.max()) srcList = [ FDEM.Src.MagDipole([bzr], freq, srcLoc, orientation='Z') for freq in freqs ] surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigma=surj1Dmap * sigma, muMap=muMap, Solver=Solver) prbFD.pair(surveyFD) std = 0.03 surveyFD.makeSyntheticData(mtrue, std) surveyFD.eps = np.linalg.norm(surveyFD.dtrue) * 1e-6 # FDEM inversion np.random.seed(13472) dmisfit = DataMisfit.l2_DataMisfit(surveyFD) regMesh = Mesh.TensorMesh([mesh.hz[muMap.maps[-1].indActive]]) reg = Regularization.Simple(regMesh) opt = Optimization.InexactGaussNewton(maxIterCG=10) invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt) # Inversion Directives betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) beta = Directives.BetaSchedule(coolingFactor=4, coolingRate=3) betaest = Directives.BetaEstimate_ByEig(beta0_ratio=2.) target = Directives.TargetMisfit() directiveList = [beta, betaest, target] inv = Inversion.BaseInversion(invProb, directiveList=directiveList) m0 = mur_half * np.ones(mtrue.size) reg.alpha_s = 2e-2 reg.alpha_x = 1. prbFD.counter = opt.counter = Utils.Counter() opt.remember('xc') moptFD = inv.run(m0) dpredFD = surveyFD.dpred(moptFD) if plotIt: fig, ax = plt.subplots(1, 3, figsize=(10, 6)) fs = 13 # fontsize matplotlib.rcParams['font.size'] = fs # Plot the conductivity model ax[0].semilogx(sigma[active], mesh.vectorCCz[active], 'k-', lw=2) ax[0].set_ylim(-500, 0) ax[0].set_xlim(5e-3, 1e-1) ax[0].set_xlabel('Conductivity (S/m)', fontsize=fs) ax[0].set_ylabel('Depth (m)', fontsize=fs) ax[0].grid(which='both', color='k', alpha=0.5, linestyle='-', linewidth=0.2) ax[0].legend(['Conductivity Model'], fontsize=fs, loc=4) # Plot the permeability model ax[1].plot(mur[active], mesh.vectorCCz[active], 'k-', lw=2) ax[1].plot(moptFD, mesh.vectorCCz[active], 'b-', lw=2) ax[1].set_ylim(-500, 0) ax[1].set_xlim(0.5, 2.1) ax[1].set_xlabel('Relative Permeability', fontsize=fs) ax[1].set_ylabel('Depth (m)', fontsize=fs) ax[1].grid(which='both', color='k', alpha=0.5, linestyle='-', linewidth=0.2) ax[1].legend(['True', 'Predicted'], fontsize=fs, loc=4) # plot the data misfits - negative b/c we choose positive to be in the # direction of primary ax[2].plot(freqs, -surveyFD.dobs, 'k-', lw=2) # ax[2].plot(freqs, -surveyFD.dobs[1::2], 'k--', lw=2) ax[2].loglog(freqs, -dpredFD, 'bo', ms=6) # ax[2].loglog(freqs, -dpredFD[1::2], 'b+', markeredgewidth=2., ms=10) # Labels, gridlines, etc ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax[2].grid(which='both', alpha=0.5, linestyle='-', linewidth=0.2) ax[2].set_xlabel('Frequency (Hz)', fontsize=fs) ax[2].set_ylabel('Vertical magnetic field (-T)', fontsize=fs) # ax[2].legend(("Obs", "Pred"), fontsize=fs) ax[2].legend(("z-Obs (real)", "z-Pred (real)"), fontsize=fs) ax[2].set_xlim(freqs.max(), freqs.min()) ax[0].set_title("(a) Conductivity Model", fontsize=fs) ax[1].set_title("(b) $\mu_r$ Model", fontsize=fs) ax[2].set_title("(c) FDEM observed vs. predicted", fontsize=fs) # ax[2].set_title("(c) TDEM observed vs. predicted", fontsize=fs) plt.tight_layout(pad=1.5)
def meshBuilder(xyz, h, padDist, meshGlobal=None, expFact=1.3, meshType='TENSOR', verticalAlignment='top'): """ Function to quickly generate a Tensor mesh given a cloud of xyz points, finest core cell size and padding distance. If a meshGlobal is provided, the core cells will be centered on the underlaying mesh to reduce interpolation errors. :param numpy.ndarray xyz: n x 3 array of locations [x, y, z] :param numpy.ndarray h: 1 x 3 cell size for the core mesh :param numpy.ndarray padDist: 2 x 3 padding distances [W,E,S,N,Down,Up] [OPTIONAL] :param numpy.ndarray padCore: Number of core cells around the xyz locs :object SimPEG.Mesh: Base mesh used to shift the new mesh for overlap :param float expFact: Expension factor for padding cells [1.3] :param string meshType: Specify output mesh type: "TensorMesh" RETURNS: :object SimPEG.Mesh: Mesh object """ assert meshType in ['TENSOR', 'TREE'], ('Revise meshType. Only ' + ' TENSOR | TREE mesh ' + 'are implemented') # Get extent of points limx = np.r_[xyz[:, 0].max(), xyz[:, 0].min()] limy = np.r_[xyz[:, 1].max(), xyz[:, 1].min()] limz = np.r_[xyz[:, 2].max(), xyz[:, 2].min()] # Get center of the mesh midX = np.mean(limx) midY = np.mean(limy) if verticalAlignment == 'center': midZ = np.mean(limz) else: midZ = limz[0] nCx = int(limx[0]-limx[1]) / h[0] nCy = int(limy[0]-limy[1]) / h[1] nCz = int(np.max([ limz[0]-limz[1], int(np.min(np.r_[nCx*h[0], nCy*h[1]])/3) ]) / h[2]) if meshType == 'TENSOR': # Make sure the core has odd number of cells for centereing # on global mesh if meshGlobal is not None: nCx += 1 - int(nCx % 2) nCy += 1 - int(nCy % 2) nCz += 1 - int(nCz % 2) # Figure out paddings def expand(dx, pad): L = 0 nC = 0 while L < pad: nC += 1 L = np.sum(dx * expFact**(np.asarray(range(nC))+1)) return nC # Figure number of padding cells required to fill the space npadEast = expand(h[0], padDist[0, 0]) npadWest = expand(h[0], padDist[0, 1]) npadSouth = expand(h[1], padDist[1, 0]) npadNorth = expand(h[1], padDist[1, 1]) npadDown = expand(h[2], padDist[2, 0]) npadUp = expand(h[2], padDist[2, 1]) # Create discretization hx = [(h[0], npadWest, -expFact), (h[0], nCx), (h[0], npadEast, expFact)] hy = [(h[1], npadSouth, -expFact), (h[1], nCy), (h[1], npadNorth, expFact)] hz = [(h[2], npadDown, -expFact), (h[2], nCz), (h[2], npadUp, expFact)] # Create mesh mesh = Mesh.TensorMesh([hx, hy, hz], 'CC0') # Re-set the mesh at the center of input locations # Set origin if verticalAlignment == 'center': mesh.x0 = [midX-np.sum(mesh.hx)/2., midY-np.sum(mesh.hy)/2., midZ - np.sum(mesh.hz)/2.] elif verticalAlignment == 'top': mesh.x0 = [midX-np.sum(mesh.hx)/2., midY-np.sum(mesh.hy)/2., midZ - np.sum(mesh.hz)] else: assert NotImplementedError("verticalAlignment must be 'center' | 'top'") elif meshType == 'TREE': # 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 # equal in 3D nCx, nCy, nCz = 2**(maxLevel), 2**(maxLevel), 2**(maxLevel) # nCy = 2**(int(np.log2(extent/h[1]))+1) # nCz = 2**(int(np.log2(extent/h[2]))+1) # Define the mesh and origin mesh = Mesh.TreeMesh([np.ones(nCx)*h[0], np.ones(nCx)*h[1], np.ones(nCx)*h[2]]) # Shift mesh if global mesh is used center = np.r_[midX, midY, midZ] if meshGlobal is not None: tree = cKDTree(meshGlobal.gridCC) _, ind = tree.query(center, k=1) center = meshGlobal.gridCC[ind, :] # Set origin if verticalAlignment == 'center': mesh.x0 = np.r_[center[0] - (nCx-1)*h[0]/2., center[1] - (nCy-1)*h[1]/2., center[2] - (nCz-1)*h[2]/2.] elif verticalAlignment == 'top': mesh.x0 = np.r_[center[0] - (nCx-1)*h[0]/2., center[1] - (nCy-1)*h[1]/2., center[2] - (nCz-1)*h[2]] else: assert NotImplementedError("verticalAlignment must be 'center' | 'top'") return mesh
def set_mesh_1d(hz): return Mesh.TensorMesh([hz], x0=[0])
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.getJ(m0)**2., axis=0)**0.5 wr = wr / np.max(wr) dmis = DataMisfit.l2_DataMisfit(survey) dmis.W = 1. / wd betaest = Directives.BetaEstimate_ByEig(beta0_ratio=1e0) # Creat reduced identity map idenMap = Maps.IdentityMap(nP=mesh.nC) reg = Regularization.Sparse(mesh, mapping=idenMap) reg.mref = mref reg.cell_weights = wr reg.eps_p, reg.eps_q = 1e-1, 1e-1 reg.norms = np.c_[0., 0., 2., 2.] 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.UpdatePreconditioner() # Set the IRLS directive, penalize the lowest 25 percentile of model values # Start with an l2-l2, then switch to lp-norms IRLS = Directives.Update_IRLS(maxIRLSiter=20, minGNiter=1, f_min_change=1e-4) saveDict = Directives.SaveOutputEveryIteration(save_txt=False) inv = Inversion.BaseInversion( invProb, directiveList=[IRLS, betaest, update_Jacobi, saveDict]) # Run inversion mrec = inv.run(m0) print("Final misfit:" + str(invProb.dmisfit(mrec))) if plotIt: fig, axes = plt.subplots(2, 2, figsize=(12 * 1.2, 8 * 1.2)) for i in range(prob.G.shape[0]): axes[0, 0].plot(prob.G[i, :]) axes[0, 0].set_title('Columns of matrix G') axes[0, 1].plot(mesh.vectorCCx, mtrue, 'b-') axes[0, 1].plot(mesh.vectorCCx, invProb.l2model, 'r-') # axes[0, 1].legend(('True Model', 'Recovered Model')) axes[0, 1].set_ylim(-1.0, 1.25) axes[0, 1].plot(mesh.vectorCCx, mrec, 'k-', lw=2) axes[0, 1].legend(('True Model', 'Smooth l2-l2', 'Sparse norms: {0}'.format(*reg.norms)), fontsize=12) axes[1, 1].plot(saveDict.phi_d, 'k', lw=2) twin = axes[1, 1].twinx() twin.plot(saveDict.phi_m, 'k--', lw=2) axes[1, 1].plot(np.r_[IRLS.iterStart, IRLS.iterStart], np.r_[0, np.max(saveDict.phi_d)], 'k:') axes[1, 1].text(IRLS.iterStart, 0., 'IRLS Start', va='bottom', ha='center', rotation='vertical', size=12, bbox={'facecolor': 'white'}) axes[1, 1].set_ylabel('$\phi_d$', size=16, rotation=0) axes[1, 1].set_xlabel('Iterations', size=14) axes[1, 0].axis('off') twin.set_ylabel('$\phi_m$', size=16, rotation=0) return prob, survey, mesh, mrec
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 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(-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 MAGsurvey 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 susceptibility 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_[1, 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() # 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-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 PF.Gravity.plot_obs_2D(rxLoc, d=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') # Vertica 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)
from matplotlib.path import Path import matplotlib.patches as patches from SimPEG import Mesh, Maps, SolverLU, Utils from SimPEG.Utils import ExtractCoreMesh from SimPEG.EM.Static import DC from ..base import widgetify # Mesh, mapping can be globals global npad = 15 growrate = 2.0 cs = 0.5 hx = [(cs, npad, -growrate), (cs, 200), (cs, npad, growrate)] hy = [(cs, npad, -growrate), (cs, 100)] mesh = Mesh.TensorMesh([hx, hy], "CN") expmap = Maps.ExpMap(mesh) mapping = expmap dx = 5 xr = np.arange(-40, 41, dx) dxr = np.diff(xr) xmin = -40.0 xmax = 40.0 ymin = -40.0 ymax = 8.0 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))
def get_mesh(self): mesh = Mesh.TensorMesh([np.ones(20)]) mesh.setCellGradBC('dirichlet') return mesh
def setUp(self): hx = np.random.rand(10.) hy = np.random.rand(10.) hz = np.random.rand(10.) self.mesh = Mesh.TensorMesh([hx, hy, hz])