mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-16 11:21:38 +08:00
804 KiB
804 KiB
In [133]:
%matplotlib notebook
%pylab
from SimPEG import *
import simpegPF as PFUsing matplotlib backend: nbAgg Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['linalg', 'beta', 'inv'] `%matplotlib` prevents importing * from pylab and numpy
In [135]:
# First we need to define the direction of the inducing field
# As a simple case, we pick a vertical inducing field of magnitude 50,000nT.
# From old convention, field orientation is given as an azimuth from North
# (positive clockwise) and dip from the horizontal (positive downward).
H0 = np.array(([90.,0.,50000.]))
# Assume all induced so the magnetization M is also in the same direction
M = np.array([90,0])
# Create a mesh
dx = 5.
hxind = [(dx,5,-1.3), (dx, 20), (dx,5,1.3)]
hyind = [(dx,5,-1.3), (dx, 20), (dx,5,1.3)]
hzind = [(dx,5,-1.3),(5, 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]
topo = np.c_[mkvc(xx),mkvc(yy),mkvc(zz)] # We would usually load a topofile
actv = PF.Magnetics.getActiveTopo(mesh,topo,'N') # Go from topo to actv cells
#nC = mesh.nC
#actv = np.asarray(range(mesh.nC))
# Create active map to go from reduce space to full
actvMap = Maps.ActiveCells(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)
# Let just put the observation above the topo
Z = -np.exp( ( X**2 + Y**2 )/ 75**2 ) + mesh.vectorNz[-1] + 5.
rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
In [136]:
# First, convert the magnetization direction to Cartesian
mi = np.ones(nC) * M[0]
md = np.ones(nC) * M[1]
M_xyz = PF.Magnetics.dipazm_2_xyz( mi , md ) # Ouputs an nc x 3 array
# Create the forward model operator
F = PF.Magnetics.Intrgl_Fwr_Op(mesh,H0,M_xyz,rxLoc,actv,'tmi')Begin calculation of forward operator: tmi Done 0.0 % Done 10.0 % Done 20.0 % Done 30.0 % Done 40.0 % Done 50.0 % Done 60.0 % Done 70.0 % Done 80.0 % Done 90.0 % Done 100% ...forward operator completed!!
In [137]:
# Generate a distance weighting
wr = PF.Magnetics.get_dist_wgt(mesh,rxLoc,actv,3.,np.min(mesh.hx)/4)
wrMap = PF.BaseMag.WeightMap(nC, wr)
wr_FULL = actvMap * wr
plt.figure()
ax = subplot()
mesh.plotSlice(wr_FULL, ax = ax, normal = 'Y', ind=midx, grid=True, clim = (0, wr.max()))
title('Distance weighting')
xlabel('x');ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')Begin calculation of distance weighting for R= 3.0 Done 0.0 % Done 10.0 % Done 20.0 % Done 30.0 % Done 40.0 % Done 50.0 % Done 60.0 % Done 70.0 % Done 80.0 % Done 90.0 % Done 100% ...distance weighting completed!!
<IPython.core.display.Javascript object>
In [138]:
# We can now create a susceptibility model and generate data
# Lets start with 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.01
model = mkvc(model)
model = model[actv]
# Plot the model
figure()
ax = subplot(212)
mesh.plotSlice(actvMap * model, ax = ax, normal = 'Y', ind=midy, grid=True, clim = (-1e-3, model.max()))
title('A simple block model.')
xlabel('x');ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')
# We can now generate data
d = F.dot(model) #: this is matrix multiplication!!
data = d + randn(len(d)) # We add some random Gaussian noise (1nT)
wd = np.ones(len(data))*1. # Assign flat uncertainties
subplot(221)
imshow(d.reshape(X.shape), extent=[xr.min(), xr.max(), yr.min(), yr.max()])
title('True data.')
plt.gca().set_aspect('equal', adjustable='box')
plt.colorbar()
subplot(222)
imshow(data.reshape(X.shape), extent=[xr.min(), xr.max(), yr.min(), yr.max()])
title('Data + Noise')
plt.gca().set_aspect('equal', adjustable='box')
plt.colorbar()
Out [138]:
<IPython.core.display.Javascript object>
<matplotlib.colorbar.Colorbar instance at 0x00000000395D3E48>
In [141]:
beta_in = 1e+4
# Creat reduced identity map for topography
idenMap = Maps.IdentityMap(nP = nC)
prob = PF.Magnetics.MagneticIntegral(mesh, F, mapping = idenMap)
prob.solverOpts['accuracyTol'] = 1e-4
survey = Survey.LinearSurvey()
survey.pair(prob)
survey.dobs=data
# Initiate a simple Tikonov regularization
reg = Regularization.Simple(mesh, indActive = actv, mapping=wrMap)
reg.mref = np.zeros(nC)
reg.alpha_s = 1.
# Create pre-conditioner
diagA = np.sum(F**2.,axis=0) + beta_in*(reg.W.T*reg.W).diagonal()*(wr**2.0)
PC = Utils.sdiag(diagA**-1.)
# Creat reduced identity map
idenMap = Maps.IdentityMap(nP = nC)
# Set up the misfit function and pre-conditioner
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = wd
opt = Optimization.ProjectedGNCG(maxIter=10,lower=0.,upper=1.)
opt.approxHinv = PC
# Set up directives for the inverse problem
invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta = beta_in)
beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
target = Directives.TargetMisfit()
# The final inversion object controling all the parts above
inv = Inversion.BaseInversion(invProb, directiveList=[beta, target])
# Define a starting model (small)
m0 = np.ones(nC) * 1e-4In [142]:
mrec = inv.run(m0)SimPEG.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
***Done using same Solver and solverOpts as the problem***
=============================== Projected GNCG ===============================
# beta phi_d phi_m f |proj(x-g)-x| LS Comment
-----------------------------------------------------------------------------
0 1.00e+04 6.75e+04 3.37e-04 6.75e+04 8.30e+01 0
1 5.00e+03 2.77e+03 3.19e-02 2.93e+03 6.90e+01 0
2 2.50e+03 4.03e+02 5.53e-02 5.41e+02 7.04e+01 0
3 1.25e+03 2.15e+02 5.75e-02 2.87e+02 6.99e+01 0 Skip BFGS
4 6.25e+02 2.00e+02 5.82e-02 2.37e+02 7.31e+01 0 Skip BFGS
------------------------- STOP! -------------------------
1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 6.7516e+03
1 : |xc-x_last| = 3.1475e-03 <= tolX*(1+|x0|) = 1.0111e-01
0 : |proj(x-g)-x| = 7.3120e+01 <= tolG = 1.0000e-01
0 : |proj(x-g)-x| = 7.3120e+01 <= 1e3*eps = 1.0000e-02
0 : maxIter = 10 <= iter = 5
------------------------- DONE! -------------------------
In [143]:
# Here is the recovered susceptibility model
plt.figure()
ax = subplot(121)
mesh.plotSlice(actvMap * mrec, ax = ax, normal = 'Z', ind=-2, clim = (-1e-3, model.max()))
title('Recovered model.')
xlabel('x');ylabel('y')
plt.gca().set_aspect('equal', adjustable='box')
# Horizontalsection
ax = subplot(122)
mesh.plotSlice(actvMap * mrec, ax = ax, normal = 'Y', ind=midx, clim = (-1e-3, model.max()))
title('Recovered model.')
xlabel('x');ylabel('z')
plt.gca().set_aspect('equal', adjustable='box')
<IPython.core.display.Javascript object>
In [144]:
# Plot predicted data and residual
plt.figure()
pred = F.dot(mrec) #: this is matrix multiplication!!
subplot(221)
imshow(data.reshape(X.shape))
title('Observed data.')
plt.gca().set_aspect('equal', adjustable='box')
colorbar()
subplot(222)
imshow(pred.reshape(X.shape))
title('Predicted data.')
plt.gca().set_aspect('equal', adjustable='box')
colorbar()
subplot(223)
imshow(data.reshape(X.shape) - pred.reshape(X.shape))
title('Residual data.')
plt.gca().set_aspect('equal', adjustable='box')
colorbar()
subplot(224)
imshow( (data.reshape(X.shape) - pred.reshape(X.shape)) / wd.reshape(X.shape) )
title('Normalized Residual')
plt.gca().set_aspect('equal', adjustable='box')
colorbar()Out [144]:
<IPython.core.display.Javascript object>
<matplotlib.colorbar.Colorbar instance at 0x000000003D2A8FC8>
In [ ]: