bx, bz running and passing, ey failing adjoint --> I think the initial fields are not being taken care of correctly in the deriv

This commit is contained in:
Lindsey Heagy
2016-03-13 14:02:32 -07:00
parent 605e19eb22
commit fe91312917
4 changed files with 51 additions and 34 deletions
+18 -15
View File
@@ -7,7 +7,7 @@ from SimPEG.Utils import Zero, Identity
class Fields(SimPEG.Problem.TimeFields):
"""
Fancy Field Storage for a TDEM 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
@@ -29,7 +29,7 @@ class Fields(SimPEG.Problem.TimeFields):
"""
knownFields = {}
dtype = float
dtype = float
@@ -40,7 +40,7 @@ class Fields_Derivs(Fields):
'hDeriv': 'E',
'jDeriv': 'F'
}
class Fields_b(Fields):
"""Fancy Field Storage for a TDEM survey."""
@@ -65,7 +65,7 @@ class Fields_b(Fields):
def _bDeriv_m(self, tInd, src, v, adjoint=False):
return Zero()
def _bDeriv(self, tInd, src, dun_dm_v, v, adjoint=False):
def _bDeriv(self, tInd, src, dun_dm_v, v, adjoint=False):
if adjoint is True:
return self._bDeriv_u(tInd, src, v, adjoint), self._bDeriv_m(tInd, src, v, adjoint)
return self._bDeriv_u(tInd, src, dun_dm_v) + self._bDeriv_m(tInd, src, v)
@@ -73,27 +73,30 @@ class Fields_b(Fields):
def _e(self, bSolution, srcList, tInd):
e = self.MeSigmaI * ( self.edgeCurl.T * ( self.MfMui * bSolution ) )
for i, src in enumerate(srcList):
_, S_e = src.eval(self.survey.prob, self.survey.prob.times[tInd])
_, S_e = src.eval(self.survey.prob, self.survey.prob.times[tInd])
e[:,i] = e[:,i] - self.MeSigmaI * S_e
return e
return e
def _eDeriv_u(self, tInd, src, dun_dm_v, adjoint = False):
if adjoint is True:
raise NotImplementedError
return self.MfMui.T * ( self.edgeCurl * ( self.MeSigmaI.T * dun_dm_v ) )
return self.MeSigmaI * ( self.edgeCurl.T * ( self.MfMui * dun_dm_v ) )
def _eDeriv_m(self, tInd, src, v, adjoint = False):
if adjoint is True:
raise NotImplementedError
_, S_e = src.eval(self.survey.prob, self.survey.prob.times[tInd])
bSolution = self[[src],'bSolution',tInd]
_, S_e = src.eval(self.survey.prob, self.survey.prob.times[tInd])
_, S_eDeriv = src.evalDeriv(self.survey.prob.times[tInd], self, v=v)
if adjoint:
v = self.MeSigmaI.T * v
return self.MeSigmaIDeriv(self.edgeCurl.T * ( self.MfMui * bSolution) ) * v - self.MeSigmaIDeriv(S_e) * v - self.MeSigmaI * S_eDeriv
_, S_eDeriv_v = src.evalDeriv(self.survey.prob.times[tInd], self, v=v, adjoint=adjoint)
def _eDeriv(self, tInd, src, dun_dm_v, v, adjoint=False):
if adjoint is True:
raise NotImplementedError
return self.MeSigmaIDeriv(-S_e + self.edgeCurl.T * ( self.MfMui * bSolution ) ).T * v - S_eDeriv_v
return self.MeSigmaIDeriv(-S_e + self.edgeCurl.T * ( self.MfMui * bSolution)) * v - self.MeSigmaI * S_eDeriv_v
def _eDeriv(self, tInd, src, dun_dm_v, v, adjoint=False):
if adjoint is True:
return self._eDeriv_u(tInd, src, v, adjoint), self._eDeriv_m(tInd, src, v, adjoint)
return self._eDeriv_u(tInd, src, dun_dm_v) + self._eDeriv_m(tInd, src, v)
+16 -8
View File
@@ -163,20 +163,25 @@ class BaseTDEMProblem(Problem.BaseTimeProblem, BaseEMProblem):
# Loop over sources and receivers to create a fields object: PT_v, df_duT_v, df_dmT_v
for src in self.survey.srcList:
PT_v = Fields_Derivs(self.mesh, self.survey) # initialize storage for PT_v (don't need to preserve over sources)
# initialize size
df_duT_v[src, '%sDeriv'%self._fieldType, :]= np.zeros_like(u[src, self._fieldType, :])
df_duT_v[src, '%sDeriv'%self._fieldType, :] = np.zeros_like(u[src, self._fieldType, :])
for rx in src.rxList:
curPT_v = rx.evalDeriv(src, self.mesh, self.timeMesh, Utils.mkvc(v[src,rx]), adjoint=True)
PT_v = np.reshape(curPT_v,(len(curPT_v)/self.timeMesh.nN, self.timeMesh.nN), order='F')
PT_v[src,'%sDeriv'%rx.projField,:] = rx.evalDeriv(src, self.mesh, self.timeMesh, Utils.mkvc(v[src,rx]), adjoint=True)
# PT_v = np.reshape(curPT_v,(len(curPT_v)/self.timeMesh.nN, self.timeMesh.nN), order='F')
df_duTFun = getattr(u, '_%sDeriv'%rx.projField, None)
df_duT_v_cur, df_dmT_v = df_duTFun(None, src, None, PT_v, adjoint=True)
JTv = JTv + df_dmT_v
for tInd in range(self.nT+1):
cur = df_duTFun(tInd, src, None, Utils.mkvc(PT_v[src,'%sDeriv'%rx.projField,tInd]), adjoint=True)
df_duT_v[src, '%sDeriv'%self._fieldType, :] += df_duT_v_cur
df_duT_v[src, '%sDeriv'%self._fieldType, tInd] = df_duT_v[src, '%sDeriv'%self._fieldType, tInd] + Utils.mkvc(cur[0],2)
JTv = JTv + cur[1]
del PT_v # no longer need this
AdiagTinv = None
@@ -212,9 +217,12 @@ class BaseTDEMProblem(Problem.BaseTimeProblem, BaseEMProblem):
JTv = JTv + Utils.mkvc(-dAT_dm_v + dRHST_dm_v)
# Missing the 0 step
# adding du_dm^T * dF_du^T * P^T vfor time 0 (no dRHS_dm_v at time 0)
for src in self.survey.srcList:
JTv = JTv + self.getInitialFieldsDeriv(Utils.mkvc(df_duT_v[src,'%sDeriv'%self._fieldType,0]), adjoint=True)
for projField in set(rx.projField):
JTv = JTv + self.getInitialFieldsDeriv(Utils.mkvc(df_duT_v[src,'%sDeriv'%self._fieldType,0]), adjoint=True)
return Utils.mkvc(JTv)
+11 -9
View File
@@ -4,15 +4,15 @@ from SimPEG import EM
plotIt = False
testDeriv = False
testDeriv = True
testAdjoint = True
tol = 1e-6
TOL = 1e-5
def setUp(rxcomp='bz'):
cs = 5.
ncx = 20
ncy = 10
ncy = 15
npad = 20
hx = [(cs,ncx), (cs,npad,1.3)]
hy = [(cs,npad,-1.3), (cs,ncy), (cs,npad,1.3)]
@@ -74,7 +74,7 @@ class TDEM_DerivTests(unittest.TestCase):
tInd = 0 # not actually used
V1 = v.dot(prb.getAdiagDeriv(tInd, u, m))
V2 = m.dot(prb.getAdiagDeriv(tInd, u, v, adjoint=True))
passed = np.abs(V1-V2)/np.abs(V1) < tol
passed = np.abs(V1-V2) < TOL * (np.abs(V1) + np.abs(V2))/2.
print 'AdjointTest', V1, V2, passed
self.assertTrue(passed)
@@ -107,16 +107,18 @@ class TDEM_DerivTests(unittest.TestCase):
# ====== TEST Jtvec ========== #
def adjointJvecVsJtvecTest(self, rxcomp='bz'):
print '\n Adjoint Testing Jvec, Jtvec %s' %(rxcomp)
prb, m0, mesh = setUp(rxcomp)
print '\nAdjoint Testing Jvec, Jtvec %s' %(rxcomp)
prb, m0, mesh = setUp(rxcomp)
m = np.random.rand(prb.mapping.nP)
d = np.random.randn(prb.survey.nD)
V1 = d.dot(prb.Jvec(m0, m))
V2 = m.dot(prb.Jtvec(m0, d))
passed = np.abs(V1-V2)/np.abs(V1) < tol
print 'AdjointTest', V1, V2, passed
tol = TOL * (np.abs(V1) + np.abs(V2)) / 2.
passed = np.abs(V1-V2) < tol
print ' ', V1, V2, np.abs(V1-V2), tol, passed
self.assertTrue(passed)
if testAdjoint:
@@ -6,6 +6,7 @@ plotIt = False
testDeriv = True
testAdjoint = True
TOL = 1e-6
class TDEM_bDerivTests(unittest.TestCase):
@@ -70,8 +71,11 @@ class TDEM_bDerivTests(unittest.TestCase):
V1 = d.dot(prb.Jvec(m0, m))
V2 = m.dot(prb.Jtvec(m0, d))
print 'AdjointTest', V1, V2
self.assertTrue(np.abs(V1-V2)/np.abs(V1) < 1e-6)
tol = TOL * (np.abs(V1) + np.abs(V2)) / 2.
passed = np.abs(V1-V2) < tol
print ' ', V1, V2, np.abs(V1-V2), tol, passed
self.assertTrue(passed)