mirror of
https://github.com/wassname/simpeg.git
synced 2026-06-27 21:08:35 +08:00
FDEM Fields object docs
This commit is contained in:
@@ -7,11 +7,39 @@ from SimPEG.Utils import Zero, Identity
|
||||
|
||||
|
||||
class Fields(SimPEG.Problem.Fields):
|
||||
"""Fancy Field Storage for a FDEM survey."""
|
||||
"""
|
||||
|
||||
Fancy Field Storage for a FDEM survey. Only one field type is stored for
|
||||
each problem, the rest are computed. The fields obejct acts like an array and is indexed by
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
f = problem.fields(m)
|
||||
e = f[srcList,'e']
|
||||
b = f[srcList,'b']
|
||||
|
||||
If accessing all sources for a given field, use the :code:`:`
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
f = problem.fields(m)
|
||||
e = f[:,'e']
|
||||
b = f[:,'b']
|
||||
|
||||
The array returned will be size (nE or nF, nSrcs :math:`\\times` nFrequencies)
|
||||
"""
|
||||
|
||||
knownFields = {}
|
||||
dtype = complex
|
||||
|
||||
class Fields_e(Fields):
|
||||
"""
|
||||
Fields object for Problem_e.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
"""
|
||||
|
||||
knownFields = {'eSolution':'E'}
|
||||
aliasFields = {
|
||||
'e' : ['eSolution','E','_e'],
|
||||
@@ -30,6 +58,15 @@ class Fields_e(Fields):
|
||||
self._edgeCurl = self.survey.prob.mesh.edgeCurl
|
||||
|
||||
def _ePrimary(self, eSolution, srcList):
|
||||
"""
|
||||
Primary electric field from source
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary electric field as defined by the sources
|
||||
"""
|
||||
|
||||
ePrimary = np.zeros_like(eSolution)
|
||||
for i, src in enumerate(srcList):
|
||||
ep = src.ePrimary(self.prob)
|
||||
@@ -37,19 +74,67 @@ class Fields_e(Fields):
|
||||
return ePrimary
|
||||
|
||||
def _eSecondary(self, eSolution, srcList):
|
||||
"""
|
||||
Secondary electric field is the thing we solved for
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary electric field
|
||||
"""
|
||||
|
||||
return eSolution
|
||||
|
||||
def _e(self, eSolution, srcList):
|
||||
"""
|
||||
Total electric field is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total electric field
|
||||
"""
|
||||
|
||||
return self._ePrimary(eSolution,srcList) + self._eSecondary(eSolution,srcList)
|
||||
|
||||
def _eDeriv_u(self, src, v, adjoint = False):
|
||||
"""
|
||||
Derivative of the total electric field with respect to the thing we
|
||||
solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the electric field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
return Identity()*v
|
||||
|
||||
def _eDeriv_m(self, src, v, adjoint = False):
|
||||
"""
|
||||
Derivative of the total electric field with respect to the inversion model. Here, we assume that the primary does not depend on the model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the electric field derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming primary does not depend on the model
|
||||
return Zero()
|
||||
|
||||
def _bPrimary(self, eSolution, srcList):
|
||||
"""
|
||||
Primary magnetic flux density from source
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary magnetic flux density as defined by the sources
|
||||
"""
|
||||
|
||||
bPrimary = np.zeros([self._edgeCurl.shape[0],eSolution.shape[1]],dtype = complex)
|
||||
for i, src in enumerate(srcList):
|
||||
bp = src.bPrimary(self.prob)
|
||||
@@ -57,6 +142,15 @@ class Fields_e(Fields):
|
||||
return bPrimary
|
||||
|
||||
def _bSecondary(self, eSolution, srcList):
|
||||
"""
|
||||
Secondary magnetic flux density from eSolution
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary magnetic flux density
|
||||
"""
|
||||
|
||||
C = self._edgeCurl
|
||||
b = (C * eSolution)
|
||||
for i, src in enumerate(srcList):
|
||||
@@ -66,29 +160,85 @@ class Fields_e(Fields):
|
||||
return b
|
||||
|
||||
def _bSecondaryDeriv_u(self, src, v, adjoint = False):
|
||||
"""
|
||||
Derivative of the secondary magnetic flux density with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary magnetic flux density with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
C = self._edgeCurl
|
||||
if adjoint:
|
||||
return - 1./(1j*omega(src.freq)) * (C.T * v)
|
||||
return - 1./(1j*omega(src.freq)) * (C * v)
|
||||
|
||||
def _bSecondaryDeriv_m(self, src, v, adjoint = False):
|
||||
"""
|
||||
Derivative of the secondary magnetic flux density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the secondary magnetic flux density derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
S_mDeriv, _ = src.evalDeriv(self.prob, adjoint)
|
||||
S_mDeriv = S_mDeriv(v)
|
||||
return 1./(1j * omega(src.freq)) * S_mDeriv
|
||||
|
||||
def _b(self, eSolution, srcList):
|
||||
"""
|
||||
Total magnetic flux density is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total magnetic flux density
|
||||
"""
|
||||
|
||||
return self._bPrimary(eSolution, srcList) + self._bSecondary(eSolution, srcList)
|
||||
|
||||
def _bDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic flux density with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
# Primary does not depend on u
|
||||
return self._bSecondaryDeriv_u(src, v, adjoint)
|
||||
|
||||
def _bDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic flux density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the magnetic flux density derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# Assuming the primary does not depend on the model
|
||||
return self._bSecondaryDeriv_m(src, v, adjoint)
|
||||
|
||||
|
||||
class Fields_b(Fields):
|
||||
"""
|
||||
Fields object for Problem_b.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
"""
|
||||
|
||||
knownFields = {'bSolution':'F'}
|
||||
aliasFields = {
|
||||
'b' : ['bSolution','F','_b'],
|
||||
@@ -111,6 +261,15 @@ class Fields_b(Fields):
|
||||
self._Me = self.survey.prob.Me
|
||||
|
||||
def _bPrimary(self, bSolution, srcList):
|
||||
"""
|
||||
Primary magnetic flux density from source
|
||||
|
||||
:param numpy.ndarray bSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary electric field as defined by the sources
|
||||
"""
|
||||
|
||||
bPrimary = np.zeros_like(bSolution)
|
||||
for i, src in enumerate(srcList):
|
||||
bp = src.bPrimary(self.prob)
|
||||
@@ -118,19 +277,66 @@ class Fields_b(Fields):
|
||||
return bPrimary
|
||||
|
||||
def _bSecondary(self, bSolution, srcList):
|
||||
"""
|
||||
Secondary magnetic flux density is the thing we solved for
|
||||
|
||||
:param numpy.ndarray bSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary magnetic flux density
|
||||
"""
|
||||
|
||||
return bSolution
|
||||
|
||||
def _b(self, bSolution, srcList):
|
||||
"""
|
||||
Total magnetic flux density is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray bSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total magnetic flux density
|
||||
"""
|
||||
|
||||
return self._bPrimary(bSolution, srcList) + self._bSecondary(bSolution, srcList)
|
||||
|
||||
def _bDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic flux density with respect to the thing we
|
||||
solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector
|
||||
"""
|
||||
return Identity()*v
|
||||
|
||||
def _bDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic flux density with respect to the inversion model. Here, we assume that the primary does not depend on the model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the magnetic flux density derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming primary does not depend on the model
|
||||
return Zero()
|
||||
|
||||
def _ePrimary(self, bSolution, srcList):
|
||||
"""
|
||||
Primary electric field from source
|
||||
|
||||
:param numpy.ndarray bSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary electric field as defined by the sources
|
||||
"""
|
||||
|
||||
ePrimary = np.zeros([self._edgeCurl.shape[1],bSolution.shape[1]],dtype = complex)
|
||||
for i,src in enumerate(srcList):
|
||||
ep = src.ePrimary(self.prob)
|
||||
@@ -138,6 +344,15 @@ class Fields_b(Fields):
|
||||
return ePrimary
|
||||
|
||||
def _eSecondary(self, bSolution, srcList):
|
||||
"""
|
||||
Secondary electric field from bSolution
|
||||
|
||||
:param numpy.ndarray bSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary electric field
|
||||
"""
|
||||
|
||||
e = self._MeSigmaI * ( self._edgeCurl.T * ( self._MfMui * bSolution))
|
||||
for i,src in enumerate(srcList):
|
||||
_,S_e = src.eval(self.prob)
|
||||
@@ -145,12 +360,32 @@ class Fields_b(Fields):
|
||||
return e
|
||||
|
||||
def _eSecondaryDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary electric field with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary electric field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
if not adjoint:
|
||||
return self._MeSigmaI * ( self._edgeCurl.T * ( self._MfMui * v) )
|
||||
else:
|
||||
return self._MfMui.T * (self._edgeCurl * (self._MeSigmaI.T * v))
|
||||
|
||||
def _eSecondaryDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary electric field with respect to the inversion model
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary electric field with respect to the model with a vector
|
||||
"""
|
||||
|
||||
bSolution = self[[src],'bSolution']
|
||||
_,S_e = src.eval(self.prob)
|
||||
Me = self._Me
|
||||
@@ -174,17 +409,53 @@ class Fields_b(Fields):
|
||||
return de_dm
|
||||
|
||||
def _e(self, bSolution, srcList):
|
||||
"""
|
||||
Total electric field is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total electric field
|
||||
"""
|
||||
|
||||
return self._ePrimary(bSolution, srcList) + self._eSecondary(bSolution, srcList)
|
||||
|
||||
def _eDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total electric field with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the electric field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
return self._eSecondaryDeriv_u(src, v, adjoint)
|
||||
|
||||
def _eDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total electric field density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the electric field derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming primary doesn't depend on model
|
||||
return self._eSecondaryDeriv_m(src, v, adjoint)
|
||||
|
||||
|
||||
class Fields_j(Fields):
|
||||
"""
|
||||
Fields object for Problem_j.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
"""
|
||||
|
||||
knownFields = {'jSolution':'F'}
|
||||
aliasFields = {
|
||||
'j' : ['jSolution','F','_j'],
|
||||
@@ -207,6 +478,15 @@ class Fields_j(Fields):
|
||||
self._Me = self.survey.prob.Me
|
||||
|
||||
def _jPrimary(self, jSolution, srcList):
|
||||
"""
|
||||
Primary current density from source
|
||||
|
||||
:param numpy.ndarray jSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary current density as defined by the sources
|
||||
"""
|
||||
|
||||
jPrimary = np.zeros_like(jSolution,dtype = complex)
|
||||
for i, src in enumerate(srcList):
|
||||
jp = src.jPrimary(self.prob)
|
||||
@@ -214,19 +494,66 @@ class Fields_j(Fields):
|
||||
return jPrimary
|
||||
|
||||
def _jSecondary(self, jSolution, srcList):
|
||||
"""
|
||||
Secondary current density is the thing we solved for
|
||||
|
||||
:param numpy.ndarray jSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary current density
|
||||
"""
|
||||
|
||||
return jSolution
|
||||
|
||||
def _j(self, jSolution, srcList):
|
||||
"""
|
||||
Total current density is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray jSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total current density
|
||||
"""
|
||||
|
||||
return self._jPrimary(jSolution, srcList) + self._jSecondary(jSolution, srcList)
|
||||
|
||||
def _jDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total current density with respect to the thing we
|
||||
solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the current density with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
return Identity()*v
|
||||
|
||||
def _jDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total current density with respect to the inversion model. Here, we assume that the primary does not depend on the model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the current density derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
# assuming primary does not depend on the model
|
||||
return Zero()
|
||||
|
||||
def _hPrimary(self, jSolution, srcList):
|
||||
"""
|
||||
Primary magnetic field from source
|
||||
|
||||
:param numpy.ndarray hSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary magnetic field as defined by the sources
|
||||
"""
|
||||
|
||||
hPrimary = np.zeros([self._edgeCurl.shape[1],jSolution.shape[1]],dtype = complex)
|
||||
for i, src in enumerate(srcList):
|
||||
hp = src.hPrimary(self.prob)
|
||||
@@ -234,6 +561,15 @@ class Fields_j(Fields):
|
||||
return hPrimary
|
||||
|
||||
def _hSecondary(self, jSolution, srcList):
|
||||
"""
|
||||
Secondary magnetic field from bSolution
|
||||
|
||||
:param numpy.ndarray jSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary magnetic field
|
||||
"""
|
||||
|
||||
h = self._MeMuI * (self._edgeCurl.T * (self._MfRho * jSolution) )
|
||||
for i, src in enumerate(srcList):
|
||||
h[:,i] *= -1./(1j*omega(src.freq))
|
||||
@@ -242,12 +578,32 @@ class Fields_j(Fields):
|
||||
return h
|
||||
|
||||
def _hSecondaryDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary magnetic field with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary magnetic field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
if not adjoint:
|
||||
return -1./(1j*omega(src.freq)) * self._MeMuI * (self._edgeCurl.T * (self._MfRho * v) )
|
||||
elif adjoint:
|
||||
return -1./(1j*omega(src.freq)) * self._MfRho.T * (self._edgeCurl * ( self._MeMuI.T * v))
|
||||
|
||||
def _hSecondaryDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary magnetic field with respect to the inversion model
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary magnetic field with respect to the model with a vector
|
||||
"""
|
||||
|
||||
jSolution = self[[src],'jSolution']
|
||||
MeMuI = self._MeMuI
|
||||
C = self._edgeCurl
|
||||
@@ -272,17 +628,53 @@ class Fields_j(Fields):
|
||||
|
||||
|
||||
def _h(self, jSolution, srcList):
|
||||
"""
|
||||
Total magnetic field is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total magnetic field
|
||||
"""
|
||||
|
||||
return self._hPrimary(jSolution, srcList) + self._hSecondary(jSolution, srcList)
|
||||
|
||||
def _hDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic field with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the magnetic field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
return self._hSecondaryDeriv_u(src, v, adjoint)
|
||||
|
||||
def _hDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic field density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the magnetic field derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming the primary doesn't depend on the model
|
||||
return self._hSecondaryDeriv_m(src, v, adjoint)
|
||||
|
||||
|
||||
class Fields_h(Fields):
|
||||
"""
|
||||
Fields object for Problem_h.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
"""
|
||||
|
||||
knownFields = {'hSolution':'E'}
|
||||
aliasFields = {
|
||||
'h' : ['hSolution','E','_h'],
|
||||
@@ -303,6 +695,15 @@ class Fields_h(Fields):
|
||||
self._MfRho = self.survey.prob.MfRho
|
||||
|
||||
def _hPrimary(self, hSolution, srcList):
|
||||
"""
|
||||
Primary magnetic field from source
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary magnetic field as defined by the sources
|
||||
"""
|
||||
|
||||
hPrimary = np.zeros_like(hSolution,dtype = complex)
|
||||
for i, src in enumerate(srcList):
|
||||
hp = src.hPrimary(self.prob)
|
||||
@@ -310,19 +711,67 @@ class Fields_h(Fields):
|
||||
return hPrimary
|
||||
|
||||
def _hSecondary(self, hSolution, srcList):
|
||||
"""
|
||||
Secondary magnetic field is the thing we solved for
|
||||
|
||||
:param numpy.ndarray hSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary magnetic field
|
||||
"""
|
||||
|
||||
return hSolution
|
||||
|
||||
def _h(self, hSolution, srcList):
|
||||
"""
|
||||
Total magnetic field is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray hSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total magnetic field
|
||||
"""
|
||||
|
||||
return self._hPrimary(hSolution, srcList) + self._hSecondary(hSolution, srcList)
|
||||
|
||||
def _hDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic field with respect to the thing we
|
||||
solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the magnetic field with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
return Identity()*v
|
||||
|
||||
def _hDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total magnetic field with respect to the inversion model. Here, we assume that the primary does not depend on the model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the magnetic field derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming primary does not depend on the model
|
||||
return Zero()
|
||||
|
||||
def _jPrimary(self, hSolution, srcList):
|
||||
"""
|
||||
Primary current density from source
|
||||
|
||||
:param numpy.ndarray hSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary current density as defined by the sources
|
||||
"""
|
||||
|
||||
jPrimary = np.zeros([self._edgeCurl.shape[0], hSolution.shape[1]], dtype = complex)
|
||||
for i, src in enumerate(srcList):
|
||||
jp = src.jPrimary(self.prob)
|
||||
@@ -330,6 +779,15 @@ class Fields_h(Fields):
|
||||
return jPrimary
|
||||
|
||||
def _jSecondary(self, hSolution, srcList):
|
||||
"""
|
||||
Secondary current density from eSolution
|
||||
|
||||
:param numpy.ndarray hSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: secondary current density
|
||||
"""
|
||||
|
||||
j = self._edgeCurl*hSolution
|
||||
for i, src in enumerate(srcList):
|
||||
_,S_e = src.eval(self.prob)
|
||||
@@ -337,22 +795,70 @@ class Fields_h(Fields):
|
||||
return j
|
||||
|
||||
def _jSecondaryDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary current density with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the secondary current density with respect to the field we solved for with a vector
|
||||
"""
|
||||
|
||||
if not adjoint:
|
||||
return self._edgeCurl*v
|
||||
elif adjoint:
|
||||
return self._edgeCurl.T*v
|
||||
|
||||
def _jSecondaryDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the secondary current density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the secondary current density derivative with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
_,S_eDeriv = src.evalDeriv(self.prob, adjoint)
|
||||
S_eDeriv = S_eDeriv(v)
|
||||
return -S_eDeriv
|
||||
|
||||
def _j(self, hSolution, srcList):
|
||||
"""
|
||||
Total current density is sum of primary and secondary
|
||||
|
||||
:param numpy.ndarray eSolution: field we solved for
|
||||
:param list srcList: list of sources
|
||||
:rtype: numpy.ndarray
|
||||
:return: total current density
|
||||
"""
|
||||
|
||||
return self._jPrimary(hSolution, srcList) + self._jSecondary(hSolution, srcList)
|
||||
|
||||
def _jDeriv_u(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total current density with respect to the thing we solved for
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: numpy.ndarray
|
||||
:return: product of the derivative of the current density with respect to the field we solved for with a vector
|
||||
"""
|
||||
return self._jSecondaryDeriv_u(src,v,adjoint)
|
||||
|
||||
def _jDeriv_m(self, src, v, adjoint=False):
|
||||
"""
|
||||
Derivative of the total current density with respect to the inversion model.
|
||||
|
||||
:param SimPEG.EM.FDEM.Src src: source
|
||||
:param numpy.ndarray v: vector to take product with
|
||||
:param bool adjoint: adjoint?
|
||||
:rtype: SimPEG.Utils.Zero
|
||||
:return: product of the current density with respect to the inversion model with a vector
|
||||
"""
|
||||
|
||||
# assuming the primary does not depend on the model
|
||||
return self._jSecondaryDeriv_m(src,v,adjoint)
|
||||
|
||||
Reference in New Issue
Block a user