mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-15 11:26:09 +08:00
801 KiB
801 KiB
In [4]:
%matplotlib notebook
%pylab
from SimPEG import *
import simpegPF as PF
from simpegPF import BaseMag as MAG
Using matplotlib backend: nbAgg Populating the interactive namespace from numpy and matplotlib
WARNING: pylab import has clobbered these variables: ['linalg'] `%matplotlib` prevents importing * from pylab and numpy
In [5]:
# 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 = (50000.,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.
# Create a MAGsurvey
rxLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
rxLoc = MAG.RxObs(rxLoc)
srcField = MAG.SrcField([rxLoc],H0)
survey = MAG.LinearSurvey(srcField)
C:\Users\dominiquef.MIRAGEOSCIENCE\Documents\GIT\SimPEG\simpeg\SimPEG\Maps.py:533: FutureWarning: `ActiveCells` is deprecated and will be removed in future versions. Use `InjectActiveCells` instead FutureWarning)
In [7]:
# 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]
# Create active map to go from reduce set to full
actvMap = Maps.InjectActiveCells(mesh, actv, -100)
# Creat reduced identity map
idenMap = Maps.IdentityMap(nP = len(actv))
# 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(model)Begin calculation of forward operator: ind 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 [8]:
# 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
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 [8]:
<IPython.core.display.Javascript object>
<matplotlib.colorbar.Colorbar instance at 0x0000000016712A48>
In [25]:
# Create distance weights from our linera forward operator
wr = np.sum(prob.G**2.,axis=0)**0.5
wr = ( wr/np.max(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')<IPython.core.display.Javascript object>
In [26]:
#survey.makeSyntheticData(data, std=0.01)
survey.dobs=data
survey.std = np.ones(len(data))
survey.mtrue = model
# Create a regularization
reg = Regularization.Simple(mesh, indActive = actv, mapping = idenMap)
reg.wght = wr
# Directive to cool the trade-off parameter beta
beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
beta_in = 1e+4
# Create a jacobi pre-conditioner
diagA = np.sum(prob.G**2.,axis=0) + beta_in*(reg.W.T*reg.W).diagonal()*wr
PC = Utils.sdiag(diagA**-1.)
# Define the misfit function
dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = 1./survey.std
# Solver for the optimization problem
opt = Optimization.ProjectedGNCG(maxIter=10, lower=0.,upper=1., maxIterCG= 30, tolCG = 1e-3)
opt.approxHinv = PC
# Put everything together
invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta = beta_in)
target = Directives.TargetMisfit()
inv = Inversion.BaseInversion(invProb, directiveList=[beta,target])
m0 = np.ones(mesh.nC)*1e-4
m0 = m0[actv]In [27]:
mrec = inv.run(m0)SimPEG.InvProblem will set Regularization.mref to 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.70e+04 0.00e+00 6.70e+04 8.30e+01 0
1 5.00e+03 2.94e+03 4.20e-02 3.15e+03 6.89e+01 0
2 2.50e+03 3.61e+02 6.08e-02 5.13e+02 7.04e+01 0
3 1.25e+03 2.58e+02 5.84e-02 3.31e+02 8.36e+01 0 Skip BFGS
------------------------- STOP! -------------------------
1 : |fc-fOld| = 0.0000e+00 <= tolF*(1+|f0|) = 6.6998e+03
1 : |xc-x_last| = 8.5475e-03 <= tolX*(1+|x0|) = 1.0111e-01
0 : |proj(x-g)-x| = 8.3598e+01 <= tolG = 1.0000e-01
0 : |proj(x-g)-x| = 8.3598e+01 <= 1e3*eps = 1.0000e-02
0 : maxIter = 10 <= iter = 4
------------------------- DONE! -------------------------
In [28]:
# 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 [29]:
# Plot predicted data and residual
plt.figure()
pred = prob.fields(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 [29]:
<IPython.core.display.Javascript object>
<matplotlib.colorbar.Colorbar instance at 0x0000000020177B48>
In [ ]: