mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-17 11:32:59 +08:00
148 lines
4.8 KiB
Python
148 lines
4.8 KiB
Python
from SimPEG import Solver
|
|
from SimPEG.Problem import BaseTimeProblem
|
|
from simpegEM.Utils import Sources
|
|
from SurveyTDEM import FieldsTDEM
|
|
from scipy.constants import mu_0
|
|
from SimPEG.Utils import sdiag, mkvc
|
|
from SimPEG import Utils, Mesh
|
|
import numpy as np
|
|
|
|
|
|
class MixinInitialFieldCalc(object):
|
|
"""docstring for MixinInitialFieldCalc"""
|
|
|
|
storeTheseFields = 'b'
|
|
|
|
def getInitialFields(self):
|
|
if self.survey.txType == 'VMD_MVP':
|
|
# Vertical magnetic dipole, magnetic vector potential
|
|
F = self._getInitialFields_VMD_MVP()
|
|
else:
|
|
exStr = 'Invalid txType: ' + str(self.survey.txType)
|
|
raise Exception(exStr)
|
|
return F
|
|
|
|
def _getInitialFields_VMD_MVP(self):
|
|
if self.mesh._meshType is 'CYL':
|
|
if self.mesh.isSymmetric:
|
|
MVP = Sources.MagneticDipoleVectorPotential(self.survey.txLoc, self.mesh.gridEy, 'y')
|
|
# MVP = Sources.MagneticDipoleVectorPotential(self.survey.txLoc, np.c_[np.zeros(self.mesh.nN), self.mesh.gridN], 'x')
|
|
else:
|
|
raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!')
|
|
elif self.mesh._meshType is 'TENSOR':
|
|
MVPx = Sources.MagneticDipoleVectorPotential(self.survey.txLoc, self.mesh.gridEx, 'x')
|
|
MVPy = Sources.MagneticDipoleVectorPotential(self.survey.txLoc, self.mesh.gridEy, 'y')
|
|
MVPz = Sources.MagneticDipoleVectorPotential(self.survey.txLoc, self.mesh.gridEz, 'z')
|
|
MVP = np.concatenate((MVPx, MVPy, MVPz))
|
|
else:
|
|
raise Exception('Unknown mesh for VMD')
|
|
|
|
# Initialize field object
|
|
F = FieldsTDEM(self.mesh, 1, self.nT, store=self.storeTheseFields)
|
|
|
|
# Set initial B
|
|
F.b0 = self.mesh.edgeCurl*MVP
|
|
|
|
return F
|
|
|
|
|
|
class ProblemBaseTDEM(MixinInitialFieldCalc, BaseTimeProblem):
|
|
"""docstring for ProblemTDEM1D"""
|
|
def __init__(self, mesh, mapping=None, **kwargs):
|
|
BaseTimeProblem.__init__(self, mesh, mapping=mapping, **kwargs)
|
|
|
|
|
|
####################################################
|
|
# Physical Properties
|
|
####################################################
|
|
|
|
@property
|
|
def sigma(self):
|
|
return self._sigma
|
|
@sigma.setter
|
|
def sigma(self, value):
|
|
self._sigma = value
|
|
_sigma = None
|
|
|
|
####################################################
|
|
# Mass Matrices
|
|
####################################################
|
|
|
|
@property
|
|
def MfMui(self): return self._MfMui
|
|
|
|
@property
|
|
def MeSigma(self): return self._MeSigma
|
|
|
|
@property
|
|
def MeSigmaI(self): return self._MeSigmaI
|
|
|
|
def makeMassMatrices(self, m):
|
|
sig = self.mapping.transform(m)
|
|
self._MeSigma = self.mesh.getEdgeInnerProduct(sig)
|
|
self._MeSigmaI = Utils.sdInv(self.MeSigma)
|
|
self._MfMui = self.mesh.getFaceInnerProduct(1.0/mu_0)
|
|
|
|
|
|
def calcFields(self, sol, solType, tInd):
|
|
|
|
if solType == 'b':
|
|
b = sol
|
|
e = self.MeSigmaI*self.mesh.edgeCurl.T*self.MfMui*b
|
|
# Todo: implement non-zero js
|
|
else:
|
|
errStr = 'solType: ' + solType
|
|
raise NotImplementedError(errStr)
|
|
|
|
return {'b':b, 'e':e}
|
|
|
|
Solver = Solver
|
|
solveOpts = {}
|
|
|
|
def fields(self, m):
|
|
self.makeMassMatrices(m)
|
|
F = self.getInitialFields()
|
|
return self.forward(m, self.getRHS, self.calcFields, F=F)
|
|
|
|
|
|
def forward(self, m, RHS, CalcFields, F=None):
|
|
if F is None:
|
|
F = FieldsTDEM(self.mesh, self.survey.nTx, self.nT, store=self.storeTheseFields)
|
|
|
|
dtFact = None
|
|
for tInd, dt in enumerate(self.timeSteps):
|
|
if dt!=dtFact:
|
|
dtFact = dt
|
|
A = self.getA(tInd)
|
|
# print 'Factoring... (dt = ' + str(dt) + ')'
|
|
Asolve = self.Solver(A, **self.solveOpts)
|
|
# print 'Done'
|
|
rhs = RHS(tInd, F)
|
|
sol = Asolve.solve(rhs)
|
|
if sol.ndim == 1:
|
|
sol.shape = (sol.size,1)
|
|
newFields = CalcFields(sol, self.solType, tInd)
|
|
F.update(newFields, tInd)
|
|
return F
|
|
|
|
def adjoint(self, m, RHS, CalcFields, F=None):
|
|
if F is None:
|
|
F = FieldsTDEM(self.mesh, self.survey.nTx, self.nT, store=self.storeTheseFields)
|
|
|
|
dtFact = None
|
|
for tInd, dt in reversed(list(enumerate(self.timeSteps))):
|
|
if dt!=dtFact:
|
|
dtFact = dt
|
|
A = self.getA(tInd)
|
|
# print 'Factoring... (dt = ' + str(dt) + ')'
|
|
Asolve = Solver(A, options=self.solveOpts)
|
|
# print 'Done'
|
|
rhs = RHS(tInd, F)
|
|
sol = Asolve.solve(rhs)
|
|
if sol.ndim == 1:
|
|
sol.shape = (sol.size,1)
|
|
newFields = CalcFields(sol, self.solType, tInd)
|
|
F.update(newFields, tInd)
|
|
return F
|
|
|