Files
simpeg/simpegEM/FDEM/FieldsFDEM.py
T
2015-06-02 22:45:48 -07:00

340 lines
12 KiB
Python

from SimPEG import Survey, Problem, Utils, np, sp
from simpegEM.Utils.EMUtils import omega
class FieldsFDEM(Problem.Fields):
"""Fancy Field Storage for a FDEM survey."""
knownFields = {}
dtype = complex
class FieldsFDEM_e(FieldsFDEM):
knownFields = {'eSolution':'E'}
aliasFields = {
'e' : ['eSolution','E','_e'],
'ePrimary' : ['eSolution','E','_ePrimary'],
'eSecondary' : ['eSolution','E','_eSecondary'],
'b' : ['eSolution','F','_b'],
'bPrimary' : ['eSolution','F','_bPrimary'],
'bSecondary' : ['eSolution','F','_bSecondary']
}
def __init__(self,mesh,survey,**kwargs):
FieldsFDEM.__init__(self,mesh,survey,**kwargs)
def startup(self):
self._edgeCurl = self.survey.prob.mesh.edgeCurl
def _ePrimary(self, eSolution, srcList):
ePrimary = np.zeros_like(eSolution)
for i, src in enumerate(srcList):
ep = src.ePrimary(self.survey.prob)
if ep is not None:
ePrimary[:,i] = ep
return ePrimary
def _eSecondary(self, eSolution, srcList):
return eSolution
def _e(self, eSolution, srcList):
return self._ePrimary(eSolution,srcList) + self._eSecondary(eSolution,srcList)
def _eDeriv_u(self, src, v, adjoint = False):
return None
def _eDeriv_m(self, src, v, adjoint = False):
return None
def _bPrimary(self, eSolution, srcList):
bPrimary = np.zeros([self._edgeCurl.shape[0],eSolution.shape[1]],dtype = complex)
for i, src in enumerate(srcList):
bp = src.bPrimary(self.survey.prob)
if bp is not None:
bPrimary[:,i] += bp
return bPrimary
def _bSecondary(self, eSolution, srcList):
C = self._edgeCurl
b = (C * eSolution)
for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq))
S_m, _ = src.eval(self.survey.prob)
if S_m is not None:
b[:,i] += 1./(1j*omega(src.freq)) * S_m
return b
def _bSecondaryDeriv_u(self, src, v, adjoint = False):
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):
S_mDeriv, _ = src.evalDeriv(self.survey.prob, adjoint)
S_mDeriv = S_mDeriv(v)
if S_mDeriv is not None:
return 1./(1j * omega(src.freq)) * S_mDeriv
return None
def _b(self, eSolution, srcList):
return self._bPrimary(eSolution, srcList) + self._bSecondary(eSolution, srcList)
def _bDeriv_u(self, src, v, adjoint=False):
# Primary does not depend on u
return self._bSecondaryDeriv_u(src, v, adjoint)
def _bDeriv_m(self, src, v, adjoint=False):
# Assuming the primary does not depend on the model
return self._bSecondaryDeriv_m(src, v, adjoint)
class FieldsFDEM_b(FieldsFDEM):
knownFields = {'bSolution':'F'}
aliasFields = {
'b' : ['bSolution','F','_b'],
'bPrimary' : ['bSolution','F','_bPrimary'],
'bSecondary' : ['bSolution','F','_bSecondary'],
'e' : ['bSolution','E','_e'],
'ePrimary' : ['bSolution','E','_ePrimary'],
'eSecondary' : ['bSolution','E','_eSecondary'],
}
def __init__(self,mesh,survey,**kwargs):
FieldsFDEM.__init__(self,mesh,survey,**kwargs)
def startup(self):
self._edgeCurl = self.survey.prob.mesh.edgeCurl
self._MeSigmaI = self.survey.prob.MeSigmaI
self._MfMui = self.survey.prob.MfMui
def _bPrimary(self, bSolution, srcList):
bPrimary = np.zeros_like(bSolution)
for i, src in enumerate(srcList):
bp = src.bPrimary(self.survey.prob)
if bp is not None:
bPrimary[:,i] = bp
return bPrimary
def _bSecondary(self, bSolution, srcList):
return bSolution
def _b(self, bSolution, srcList):
return self._bPrimary(bSolution, srcList) + self._bSecondary(bSolution, srcList)
def _ePrimary(self, bSolution, srcList):
ePrimary = np.zeros([self._edgeCurl.shape[1],bSolution.shape[1]],dtype = complex)
for i,src in enumerate(srcList):
ep = src.ePrimary(self.survey.prob)
if ep is not None:
ePrimary[:,i] = ep
return ePrimary
def _eSecondary(self, bSolution, srcList):
e = self._MeSigmaI * ( self._edgeCurl.T * ( self._MfMui * bSolution))
for i,src in enumerate(srcList):
_,S_e = src.eval(self.survey.prob)
if S_e is not None:
e += -self._MeSigmaI*S_e
return e
def _e(self, bSolution, srcList):
return self._ePrimary(bSolution, srcList) + self._eSecondary(bSolution, srcList)
def _eDeriv(self, bSolution, srcList, v, adjoint=False):
raise NotImplementedError('Fields Derivs Not Implemented Yet')
_,S_eDeriv = src.evalDeriv(self.survey.prob, adjoint)
S_eDeriv = S_eDeriv(v)
if S_eDeriv is None:
return None
else:
return -S_eDeriv
class FieldsFDEM_j(FieldsFDEM):
knownFields = {'jSolution':'F'}
aliasFields = {
'j' : ['jSolution','F','_j'],
'jPrimary' : ['jSolution','F','_jPrimary'],
'jSecondary' : ['jSolution','F','_jSecondary'],
'h' : ['jSolution','E','_h'],
'hPrimary' : ['jSolution','E','_hPrimary'],
'hSecondary' : ['jSolution','E','_hSecondary'],
}
def __init__(self,mesh,survey,**kwargs):
FieldsFDEM.__init__(self,mesh,survey,**kwargs)
def startup(self):
self._edgeCurl = self.survey.prob.mesh.edgeCurl
self._MeMuI = self.survey.prob.MeMuI
self._MfRho = self.survey.prob.MfRho
self._curModel = self.survey.prob.curModel
def _jPrimary(self, jSolution, srcList):
jPrimary = np.zeros_like(jSolution)
for i, src in enumerate(srcList):
jp = src.jPrimary(self.survey.prob)
if jp is not None:
jPrimary[:,i] += jp
return jPrimary
def _jSecondary(self, jSolution, srcList):
return jSolution
def _j(self, jSolution, srcList):
return self._jPrimary(jSolution, srcList) + self._jSecondary(jSolution, srcList)
def _hPrimary(self, jSolution, srcList):
hPrimary = np.zeros([self._edgeCurl.shape[1],jSolution.shape[1]],dtype = complex)
for i, src in enumerate(srcList):
hp = src.hPrimary(self.survey.prob)
if hp is not None:
hPrimary[:,i] = hp
return hPrimary
def _hSecondary(self, jSolution, srcList):
MeMuI = self._MeMuI
C = self._edgeCurl
MfRho = self._MfRho
h = MeMuI * (C.T * (MfRho * jSolution) )
for i, src in enumerate(srcList):
h[:,i] *= -1./(1j*omega(src.freq))
S_m,_ = src.eval(self.survey.prob)
if S_m is not None:
h[:,i] += 1./(1j*omega(src.freq)) * MeMuI * S_m
return h
def _h(self, jSolution, srcList):
return self._hPrimary(jSolution, srcList) + self._hSecondary(jSolution, srcList)
def _hDeriv(self, jSolution, srcList, v, adjoint=False):
raise NotImplementedError('Fields Derivs Not Implemented Yet')
sig = self._curModel.transform
sigi = 1/sig
dsig_dm = self._curModel.transformDeriv
dsigi_dsig = -Utils.sdiag(sigi)**2
dMf_dsigi = self.mesh.getFaceInnerProductDeriv(sigi)(j)
sigi = self._MfRho
S_mDeriv,_ = src.getSourceDeriv(self.survey.prob, v, adjoint)
if not adjoint:
h_Deriv= -(1./(1j*omega(freq))) * MeMuI * ( C.T * ( dMf_dsigi * ( dsigi_dsig * ( dsig_dm * v ) ) ) )
else:
h_Deriv= -(1./(1j*omega(freq))) * dsig_dm.T * ( dsigi_dsig.T * ( dMf_dsigi.T * ( C * ( MeMuI.T * v ) ) ) )
if S_mDeriv is not None:
return 1./(1j*omega(src.freq)) * S_mDeriv + h_Deriv
class FieldsFDEM_h(FieldsFDEM):
knownFields = {'hSolution':'E'}
aliasFields = {
'h' : ['hSolution','E','_h'],
'hPrimary' : ['hSolution','E','_hPrimary'],
'hSecondary' : ['hSolution','E','_hSecondary'],
'j' : ['hSolution','F','_j'],
'jPrimary' : ['hSolution','F','_jPrimary'],
'jSecondary' : ['hSolution','F','_jSecondary']
}
def __init__(self,mesh,survey,**kwargs):
FieldsFDEM.__init__(self,mesh,survey,**kwargs)
def startup(self):
self._edgeCurl = self.survey.prob.mesh.edgeCurl
self._MeMuI = self.survey.prob.MeMuI
self._MfRho = self.survey.prob.MfRho
def _hPrimary(self, hSolution, srcList):
hPrimary = np.zeros_like(hSolution)
for i, src in enumerate(srcList):
hp = src.hPrimary(self.survey.prob)
if hp is not None:
hPrimary[:,i] += hp
return hPrimary
def _hSecondary(self, hSolution, srcList):
return hSolution
def _h(self, hSolution, srcList):
return self._hPrimary(hSolution, srcList) + self._hSecondary(hSolution, srcList)
def _jPrimary(self, hSolution, srcList):
jPrimary = np.zeros([self._edgeCurl.shape[0], hSolution.shape[1]])
for i, src in enumerate(srcList):
jp = src.jPrimary(self.survey.prob)
if jp is not None:
jPrimary[:,i] = jp
return jPrimary
def _jSecondary(self, hSolution, srcList):
j = self._edgeCurl*hSolution
for i, src in enumerate(srcList):
_,S_e = src.eval(self.survey.prob)
if S_e is not None:
j[:,i] += -S_e
return j
def _j(self, hSolution, srcList):
return self._jPrimary(hSolution, srcList) + self._jSecondary(hSolution, srcList)
def _jDeriv(self, hSolution, srcList, v, adjoint=False):
raise NotImplementedError('Fields Derivs Not Implemented Yet')
_,S_eDeriv = src.getSourceDeriv(self.survey.prob, v, adjoint)
if S_eDeriv is None:
return None
else:
return - S_eDeriv
# def calcFields(self, sol, freq, fieldType, adjoint=False):
# j = sol
# if fieldType == 'j':
# return j
# elif fieldType == 'h':
# MeMuI = self._MeMuI
# C = self.mesh.edgeCurl
# MfRho = self._MfRho
# if not adjoint:
# h = -(1./(1j*omega(freq))) * MeMuI * ( C.T * ( MfRho * j ) )
# else:
# h = -(1./(1j*omega(freq))) * MfRho.T * ( C * ( MeMuI.T * j ) )
# return h
# raise NotImplementedError('fieldType "%s" is not implemented.' % fieldType)
# def calcFieldsDeriv(self, sol, freq, fieldType, v, adjoint=False):
# j = sol
# if fieldType == 'j':
# return None
# elif fieldType == 'h':
# MeMuI = self._MeMuI
# C = self.mesh.edgeCurl
# sig = self._curModel.transform
# sigi = 1/sig
# dsig_dm = self._curModel.transformDeriv
# dsigi_dsig = -Utils.sdiag(sigi)**2
# dMf_dsigi = self.mesh.getFaceInnerProductDeriv(sigi)(j)
# sigi = self._MfRho
# if not adjoint:
# return -(1./(1j*omega(freq))) * MeMuI * ( C.T * ( dMf_dsigi * ( dsigi_dsig * ( dsig_dm * v ) ) ) )
# else:
# return -(1./(1j*omega(freq))) * dsig_dm.T * ( dsigi_dsig.T * ( dMf_dsigi.T * ( C * ( MeMuI.T * v ) ) ) )
# raise NotImplementedError('fieldType "%s" is not implemented.' % fieldType)
# def calcFields(self, sol, freq, fieldType, adjoint=False):
# h = sol
# if fieldType == 'j':
# C = self.mesh.edgeCurl
# if adjoint:
# return C.T*h
# return C*h
# elif fieldType == 'h':
# return h
# raise NotImplementedError('fieldType "%s" is not implemented.' % fieldType)
# def calcFieldsDeriv(self, sol, freq, fieldType, v, adjoint=False):
# return None