mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-04 18:15:18 +08:00
a9362bd38e
Conflicts: SimPEG/EM/Static/DC/ProblemDC.py Confused about ... this line self.mesh.getFaceInnerProduct(self.curModel.rho)(u)
206 lines
5.3 KiB
Python
206 lines
5.3 KiB
Python
from SimPEG import Problem
|
|
from SimPEG.EM.Base import BaseEMProblem
|
|
from SurveyDC import Survey
|
|
from FieldsDC import Fields, Fields_CC, Fields_N
|
|
from SimPEG.Utils import sdiag
|
|
import numpy as np
|
|
from SimPEG.Utils import Zero
|
|
|
|
class BaseDCProblem(BaseEMProblem):
|
|
|
|
surveyPair = Survey
|
|
fieldsPair = Fields
|
|
|
|
def fields(self, m):
|
|
self.curModel = m
|
|
f = self.fieldsPair(self.mesh, self.survey)
|
|
A = self.getA()
|
|
self.Ainv = self.Solver(A, **self.solverOpts)
|
|
RHS = self.getRHS()
|
|
u = self.Ainv * RHS
|
|
Srcs = self.survey.srcList
|
|
f[Srcs, self._solutionType] = u
|
|
return f
|
|
|
|
def Jvec(self, m, v, f=None):
|
|
|
|
if f is None:
|
|
f = self.fields(m)
|
|
|
|
self.curModel = m
|
|
|
|
Jv = self.dataPair(self.survey) #same size as the data
|
|
|
|
A = self.getA()
|
|
Ainv = self.Solver(A, **self.solverOpts)
|
|
|
|
for src in self.survey.srcList:
|
|
u_src = f[src, self._solutionType] # solution vector
|
|
dA_dm_v = self.getADeriv(u_src, v)
|
|
dRHS_dm_v = self.getRHSDeriv(src, v)
|
|
print type(dA_dm_v + dRHS_dm_v), (dA_dm_v + dRHS_dm_v).shape
|
|
du_dm_v = Ainv * ( - dA_dm_v + dRHS_dm_v )
|
|
|
|
for rx in src.rxList:
|
|
df_dmFun = getattr(f, '_%sDeriv'%rx.projField, None)
|
|
df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
|
|
Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
|
Ainv.clean()
|
|
return Utils.mkvc(Jv)
|
|
|
|
def Jtvec(self, m, v, f=None):
|
|
raise NotImplementedError
|
|
|
|
def getSourceTerm(self):
|
|
"""
|
|
takes concept of source and turns it into a matrix
|
|
"""
|
|
"""
|
|
Evaluates the sources for a given frequency and puts them in matrix form
|
|
|
|
:param float freq: Frequency
|
|
:rtype: (numpy.ndarray, numpy.ndarray)
|
|
:return: s_m, s_e (nE or nF, nSrc)
|
|
"""
|
|
|
|
Srcs = self.survey.srcList
|
|
|
|
if self._formulation is 'EB':
|
|
n = self.mesh.nN
|
|
# return NotImplementedError
|
|
|
|
elif self._formulation is 'HJ':
|
|
n = self.mesh.nC
|
|
|
|
q = np.zeros((n, len(Srcs)))
|
|
|
|
for i, src in enumerate(Srcs):
|
|
q[:,i] = src.eval(self)
|
|
return q
|
|
|
|
class Problem3D_N(BaseDCProblem):
|
|
|
|
_solutionType = 'phiSolution'
|
|
_formulation = 'EB' # N potentials means B is on faces
|
|
fieldsPair = Fields_N
|
|
|
|
def __init__(self, mesh, **kwargs):
|
|
BaseDCProblem.__init__(self, mesh, **kwargs)
|
|
|
|
def getA(self):
|
|
"""
|
|
|
|
Make the A matrix for the cell centered DC resistivity problem
|
|
|
|
A = D MfRhoI D^\\top V
|
|
|
|
"""
|
|
|
|
# TODO: this won't work for full anisotropy
|
|
MeSigma = self.MeSigma
|
|
Grad = self.mesh.nodalGrad
|
|
A = Grad.T * MeSigma * Grad
|
|
# if self._makeASymmetric is True:
|
|
# return V.T * A
|
|
return A
|
|
|
|
def getADeriv(self, u, v, adoint=False):
|
|
"""
|
|
|
|
Product of the derivative of our system matrix with respect to the model and a vector
|
|
|
|
"""
|
|
return Div*self.MfRhoIDeriv(Div.T*u)
|
|
|
|
|
|
def getRHS(self):
|
|
"""
|
|
RHS for the DC problem
|
|
|
|
q
|
|
"""
|
|
|
|
RHS = self.getSourceTerm()
|
|
# if self._makeASymmetric is True:
|
|
# return self.Vol.T * RHS
|
|
return RHS
|
|
|
|
def getRHSDeriv(self, src, v, adjoint=False):
|
|
"""
|
|
Derivative of the right hand side with respect to the model
|
|
"""
|
|
qDeriv = src.evalDeriv(self, adjoint=adjoint)
|
|
return qDeriv
|
|
|
|
class Problem3D_CC(BaseDCProblem):
|
|
|
|
_solutionType = 'phiSolution'
|
|
_formulation = 'HJ' # CC potentials means J is on faces
|
|
fieldsPair = Fields_CC
|
|
|
|
def __init__(self, mesh, **kwargs):
|
|
BaseDCProblem.__init__(self, mesh, **kwargs)
|
|
|
|
def getA(self):
|
|
"""
|
|
|
|
Make the A matrix for the cell centered DC resistivity problem
|
|
|
|
A = D MfRhoI D^\\top V
|
|
|
|
"""
|
|
|
|
V = self.Vol
|
|
D = V * self.mesh.faceDiv
|
|
# TODO: this won't work for full anisotropy
|
|
MfRhoI = self.MfRhoI
|
|
A = D * MfRhoI * D.T
|
|
|
|
# I think we should deprecate this for DC problem.
|
|
# if self._makeASymmetric is True:
|
|
# return V.T * A
|
|
return A
|
|
|
|
def getADeriv(self, u, v, adjoint= False):
|
|
|
|
V = self.Vol
|
|
D = V * self.mesh.faceDiv
|
|
MfRhoIDeriv = self.MfRhoIDeriv
|
|
|
|
if adjoint:
|
|
# if self._makeASymmetric is True:
|
|
# v = V * v
|
|
return D * MfRhoIDeriv(D * v)
|
|
|
|
# I think we should deprecate this for DC problem.
|
|
# if self._makeASymmetric is True:
|
|
# return V.T * ( D * ( MfRhoIDeriv( D.T * ( V * u ) ) * v ) )
|
|
return D * (MfRhoIDeriv( D.T * u ) * v)
|
|
|
|
def getRHS(self):
|
|
"""
|
|
RHS for the DC problem
|
|
|
|
q
|
|
"""
|
|
|
|
RHS = self.getSourceTerm()
|
|
|
|
# I think we should deprecate this for DC problem.
|
|
# if self._makeASymmetric is True:
|
|
# return self.Vol.T * RHS
|
|
|
|
return RHS
|
|
|
|
def getRHSDeriv(self, src, v, adjoint=False):
|
|
"""
|
|
Derivative of the right hand side with respect to the model
|
|
"""
|
|
# TODO: add qDeriv for RHS depending on m
|
|
# qDeriv = src.evalDeriv(self, adjoint=adjoint)
|
|
# return qDeriv
|
|
return Zero()
|
|
|
|
|
|
|