mirror of
https://github.com/wassname/simpeg.git
synced 2026-06-30 18:52:05 +08:00
Working for jacobian
This commit is contained in:
+4
-1
@@ -49,6 +49,9 @@ class BaseMagData(Data.BaseData):
|
||||
return bfz
|
||||
|
||||
# return np.sqrt(bfx**2 + bfy**2 + bfz**2)
|
||||
|
||||
|
||||
# return np.sqrt(bfx**2 + bfy**2 + bfz**2)
|
||||
|
||||
@Utils.count
|
||||
def projectFieldsDeriv(self, B):
|
||||
@@ -69,7 +72,7 @@ class BaseMagData(Data.BaseData):
|
||||
bfy = self.Qfy*B
|
||||
bfz = self.Qfz*B
|
||||
|
||||
return np.c_[bfx, bfy, bfz]
|
||||
return np.r_[bfx, bfy, bfz]
|
||||
|
||||
class MagDataBx(object):
|
||||
"""docstring for MagDataBx"""
|
||||
|
||||
@@ -120,7 +120,7 @@ def CongruousMagBC(mesh, Bo, chi):
|
||||
|
||||
Bbcz = const/(rfun(mesh.gridFz[(indzd|indzu),:])**3)*(3*mdotrz*(mesh.gridFz[(indzd|indzu),2]-zc)/rfun(mesh.gridFz[(indzd|indzu),:])-mz)
|
||||
|
||||
return np.r_[Bbcx, Bbcy, Bbcz]
|
||||
return np.r_[Bbcx, Bbcy, Bbcz], (1/gamma-1/(3+gamma))*1/V
|
||||
|
||||
|
||||
def MagSphereAnalFunA(x, y, z, R, xc, yc, zc, chi, Bo, flag):
|
||||
@@ -179,6 +179,15 @@ def MagSphereAnalFunA(x, y, z, R, xc, yc, zc, chi, Bo, flag):
|
||||
|
||||
return Bx, By, Bz
|
||||
|
||||
def IDTtoxyz(Inc, Dec, Btot):
|
||||
"""
|
||||
Convert from Inclination, Declination, Total intensity of earth field to x, y, z
|
||||
"""
|
||||
Bx = Btot*np.cos(Inc/180.*np.pi)*np.sin(Dec/180.*np.pi)
|
||||
By = Btot*np.cos(Inc/180.*np.pi)*np.cos(Dec/180.*np.pi)
|
||||
Bz = -Btot*np.sin(Inc/180.*np.pi)
|
||||
|
||||
return np.r_[Bx, By, Bz]
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -195,7 +204,7 @@ if __name__ == '__main__':
|
||||
sph_ind = spheremodel(M3, 0, 0, 0, 100)
|
||||
chi[sph_ind] = chiblk
|
||||
mu = (1.+chi)*mu0
|
||||
Bbc = CongruousMagBC(M3, np.array([1., 0., 0.]), chi)
|
||||
Bbc, const = CongruousMagBC(M3, np.array([1., 0., 0.]), chi)
|
||||
|
||||
flag = 'secondary'
|
||||
Box = 1.
|
||||
|
||||
+95
-36
@@ -6,7 +6,9 @@ from MagAnalytics import spheremodel, CongruousMagBC
|
||||
|
||||
|
||||
class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
"""Secondary field approach using differential equations!"""
|
||||
"""
|
||||
Secondary field approach using differential equations!
|
||||
"""
|
||||
|
||||
dataPair = BaseMag.BaseMagData
|
||||
modelPair = BaseMag.BaseMagModel
|
||||
@@ -32,10 +34,12 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
|
||||
def makeMassMatrices(self, m):
|
||||
mu = self.model.transform(m)
|
||||
self._MfMui = self.mesh.getFaceInnerProduct(1./mu)
|
||||
self._MfMui = self.mesh.getFaceMass(1./mu)
|
||||
# self._MfMui = self.mesh.getFaceInnerProduct(1./mu)
|
||||
#TODO: this will break if tensor mu
|
||||
self._MfMuI = Utils.sdiag(1./self._MfMui.diagonal())
|
||||
self._MfMu0 = self.mesh.getFaceInnerProduct(1/mu_0)
|
||||
self._MfMu0 = self.mesh.getFaceMass(1/mu_0)
|
||||
# self._MfMu0 = self.mesh.getFaceInnerProduct(1/mu_0)
|
||||
|
||||
def getB0(self):
|
||||
b0 = self.data.B0
|
||||
@@ -51,10 +55,12 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
Mc = Utils.sdiag(self.mesh.vol)
|
||||
|
||||
chi = self.model.transform(m, asMu=False)
|
||||
Bbc = CongruousMagBC(self.mesh, self.data.B0, chi)
|
||||
|
||||
Bbc, const = CongruousMagBC(self.mesh, self.data.B0, chi)
|
||||
self.Bbc_const = const
|
||||
self.Bbc = Bbc
|
||||
#TODO: put congrous BC back in
|
||||
return self._Div*self.MfMuI*self.MfMu0*B0 - self._Div*B0 #+ Mc*Dface*self._Pout.T*Bbc
|
||||
# return self._Div*self.MfMuI*self.MfMu0*B0 - self._Div*B0 #+ Mc*Dface*self._Pout.T*Bbc
|
||||
return self._Div*self.MfMuI*self.MfMu0*B0 - self._Div*B0 + Mc*Dface*self._Pout.T*Bbc
|
||||
|
||||
def getA(self, m):
|
||||
"""
|
||||
@@ -62,10 +68,13 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
|
||||
The A matrix has the form:
|
||||
|
||||
.. math::
|
||||
.. math ::
|
||||
|
||||
\mathbf{A} = \mathbf{D}\mu\mathbf{G}u
|
||||
\mathbf{A}\mathbf{u} = \mathbf{rhs}
|
||||
|
||||
\mathbf{A} = - \Div(\MfMui)^{-1}\Div^{T}
|
||||
|
||||
\mathbf{rhs} = - \Div(\MfMui)^{-1}\mathbf{M}^f_{\\frac{1}{\mu_0}}\mathbf{B}_0 + \Div\mathbf{B}_0-\diag(v)\mathbf{D} \mathbf{P}_{out}^T \mathbf{B}_{sBC}
|
||||
|
||||
|
||||
"""
|
||||
@@ -78,27 +87,70 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
rhs = self.getRHS(m)
|
||||
|
||||
m1 = sp.linalg.interface.aslinearoperator(Utils.sdiag(1/A.diagonal()))
|
||||
phi, info = sp.linalg.bicgstab(A, rhs, tol=1e-6, maxiter=1000, M=m1)
|
||||
u, info = sp.linalg.bicgstab(A, rhs, tol=1e-6, maxiter=1000, M=m1)
|
||||
|
||||
B0 = self.getB0()
|
||||
|
||||
B = self.MfMuI*self.MfMu0*B0-B0-self.MfMuI*self._Div.T*phi
|
||||
B = self.MfMuI*self.MfMu0*B0-B0-self.MfMuI*self._Div.T*u
|
||||
|
||||
#TODO: Create a mag fields object class.
|
||||
# F = self.getInitialFields()
|
||||
# e.g. {'B': B, 'phi': phi}
|
||||
return B
|
||||
# e.g. {'B': B, 'u': u}
|
||||
|
||||
return {'B': B, 'u': u}
|
||||
|
||||
# return self.forward(m, self.getRHS, self.calcFields, F=F)
|
||||
|
||||
@Utils.timeIt
|
||||
def Jvec(self, m, v, u=None):
|
||||
"""
|
||||
Computing Jacobian multiplied by vector
|
||||
|
||||
By setting our problem as
|
||||
|
||||
.. math ::
|
||||
|
||||
\mathbf{C}(\mathbf{m}, \mathbf{u}) = \mathbf{A}\mathbf{u} - \mathbf{rhs} = 0
|
||||
|
||||
And taking derivative w.r.t m
|
||||
|
||||
.. math ::
|
||||
|
||||
\\nabla \mathbf{C}(\mathbf{m}, \mathbf{u}) = \\nabla_m \mathbf{C}(\mathbf{m}) \delta \mathbf{m} +
|
||||
\\nabla_u \mathbf{C}(\mathbf{u}) \delta \mathbf{u} = 0
|
||||
|
||||
\\frac{\delta \mathbf{u}}{\delta \mathbf{m}} = - [\\nabla_u \mathbf{C}(\mathbf{u})]^{-1}\\nabla_m \mathbf{C}(\mathbf{m})
|
||||
|
||||
With some linear algebra we can have
|
||||
|
||||
.. math ::
|
||||
|
||||
\\nabla_u \mathbf{C}(\mathbf{u}) = \mathbf{A}
|
||||
|
||||
\\nabla_m \mathbf{C}(\mathbf{m}) =
|
||||
\\frac{\partial \mathbf{A}}{\partial \mathbf{m}}(\mathbf{m})\mathbf{u} - \\frac{\partial \mathbf{rhs}(\mathbf{m})}{\partial \mathbf{m}}
|
||||
|
||||
.. math ::
|
||||
|
||||
\\frac{\partial \mathbf{A}}{\partial \mathbf{m}}(\mathbf{m})\mathbf{u} =
|
||||
\\frac{\partial \mathbf{\mu}}{\partial \mathbf{m}} \left[\Div \diag (\Div^T \mathbf{u}) \dMfMuI \\right]
|
||||
|
||||
\dMfMuI = \diag(\MfMui)^{-1}_{vec} \mathbf{Av}_{F2CC}^T\diag(\mathbf{v})\diag(\\frac{1}{\mu^2})
|
||||
|
||||
\\frac{\partial \mathbf{rhs}(\mathbf{m})}{\partial \mathbf{m}} = \\frac{\partial \mathbf{\mu}}{\partial \mathbf{m}} \left[
|
||||
\Div \diag(\M^f_{\mu_{0}^{-1} \mathbf{B}_0}) \dMfMuI \\right] - \diag(\mathbf{v})\mathbf{D} \mathbf{P}_{out}^T\\frac{\partial B_{sBC}}{\partial \mathbf{m}}
|
||||
|
||||
|
||||
"""
|
||||
if u is None:
|
||||
u = self.fields(m)
|
||||
|
||||
#TODO: B, phi = u['B'], u['phi']
|
||||
#TODO: B, u = u['B'], u['u']
|
||||
|
||||
B, u = u['B'], u['u']
|
||||
|
||||
mu = self.model.transform(m, asMu=True)
|
||||
dmudm = self.model.transform(m, asMu=True)
|
||||
|
||||
P = self.data.projectFieldsDeriv(u)
|
||||
|
||||
@@ -110,23 +162,30 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
|
||||
#TODO: only works for diagonal MfMui
|
||||
# Some chain rule!
|
||||
harm_dm = Utils.sdiag(self.MfMui.diagonal()**(-2))
|
||||
MfMu_dm = self.mesh.getFaceMassDeriv()
|
||||
dmuI_dm = Utils.sdiag(mu**(-2))
|
||||
mT_dm = self.model.transformDeriv(m, asMu=True)
|
||||
|
||||
D = self._Div
|
||||
|
||||
# harm_dm = Utils.sdiag(self.MfMui.diagonal()**(-2))
|
||||
# MfMu_dm = self.mesh.getFaceMassDeriv()
|
||||
# dmuI_dm = Utils.sdiag(mu**(-2))
|
||||
# mT_dm = self.model.transformDeriv(m, asMu=True)
|
||||
|
||||
getFIPconst = 1./3
|
||||
MfMuIvec = 1/self.MfMui.diagonal()*getFIPconst
|
||||
dMfMuI = Utils.sdiag(MfMuIvec**2)*self.mesh.aveF2CC.T*Utils.sdiag(self.mesh.vol*1./mu**2)
|
||||
|
||||
Div = self._Div
|
||||
# lots-o-bracket for vector multiplication first!
|
||||
MfMu_dmXv = harm_dm * ( MfMu_dm * ( dmuI_dm * ( mT_dm * v ) ) )
|
||||
dCdm_A = D * ( Utils.sdiag( D.T * phi ) * MfMu_dmXv )
|
||||
# MfMu_dmXv = harm_dm * ( MfMu_dm * ( dmuI_dm * ( mT_dm * v ) ) )
|
||||
#dCdm_A = D * ( Utils.sdiag( D.T * u ) * MfMu_dmXv )
|
||||
|
||||
dCdm_A = dmudm*Div * ( Utils.sdiag( Div.T * u * dMfMuI ) )
|
||||
|
||||
# rhs = D * MfMuI * MfMu0 * B0
|
||||
|
||||
B0 = self.getB0()
|
||||
|
||||
#TODO: add congrous stuff
|
||||
dCdm_RHS = D * Utils.sdiag( self.MfMu0*B0 ) * MfMu_dmXv
|
||||
dCdm_RHS = dmudm* Div * Utils.sdiag( self.MfMu0*B0 ) * dMfMuI - Utils.sdiag(self.mesh.vol)*self.mesh.faceDiv*self.Pout.T*self.Bbc*self.Bbc_const
|
||||
|
||||
|
||||
# c(m,u) = A(m)u - rhs(m)
|
||||
@@ -134,9 +193,9 @@ class MagneticsDiffSecondary(Problem.BaseProblem):
|
||||
|
||||
solve = Solver(dCdu)
|
||||
|
||||
#TODO: Multiply by the dP(phi(m))/dphi
|
||||
# We transformed phi in our fields object.
|
||||
# ( dBdphi * + dBdm(phi) )
|
||||
#TODO: Multiply by the dP(u(m))/du
|
||||
# We transformed u in our fields object.
|
||||
# ( dBdu * + dBdm(u) )
|
||||
Jv = - P * solve.solve(dCdm)
|
||||
return Utils.mkvc(Jv)
|
||||
|
||||
@@ -177,24 +236,24 @@ if __name__ == '__main__':
|
||||
dpred = data.dpred(chi, u=B)
|
||||
|
||||
|
||||
##################
|
||||
# Test J
|
||||
##################
|
||||
# ##################
|
||||
# # Test J
|
||||
# ##################
|
||||
|
||||
d_chi = 0.8*chi #np.random.rand(mesh.nCz)
|
||||
d_sph_ind = spheremodel(mesh, 0., 0., -100., 50)
|
||||
d_chi[d_sph_ind] = 0.02
|
||||
# d_chi = 0.8*chi #np.random.rand(mesh.nCz)
|
||||
# d_sph_ind = spheremodel(mesh, 0., 0., -100., 50)
|
||||
# d_chi[d_sph_ind] = 0.02
|
||||
|
||||
from SimPEG.Tests import checkDerivative
|
||||
# from SimPEG.Tests import checkDerivative
|
||||
|
||||
derChk = lambda m: [prob.data.dpred(m), lambda mx: -prob.Jvec(chi, mx)]
|
||||
print '\n'
|
||||
passed = checkDerivative(derChk, chi, plotIt=False, dx=d_chi, num=2)
|
||||
# derChk = lambda m: [prob.data.dpred(m), lambda mx: -prob.Jvec(chi, mx)]
|
||||
# print '\n'
|
||||
# passed = checkDerivative(derChk, chi, plotIt=False, dx=d_chi, num=2)
|
||||
|
||||
|
||||
# plt.pcolor(X, Y, dpred.reshape(X.shape, order='F'))
|
||||
# # plt.pcolor(X, Y, dpred.reshape(X.shape, order='F'))
|
||||
|
||||
# plt.show()
|
||||
# # plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user