Files
simpeg/SimPEG/EM/FDEM/RxFDEM.py
T
2016-05-08 13:00:29 -07:00

127 lines
4.2 KiB
Python

import SimPEG
from SimPEG import sp
class BaseRx(SimPEG.Survey.BaseRx):
"""
Frequency domain receiver base class
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string real_or_imag: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, real_or_imag=None):
assert(orientation in ['x','y','z']), "Orientation %s not known. Orientation must be in 'x', 'y', 'z'. Arbitrary orientations have not yet been implemented."%orientation
assert(real_or_imag in ['real', 'imag']), "'real_or_imag' must be 'real' or 'imag', not %s"%real_or_imag
self.projComp = orientation
self.real_or_imag = real_or_imag
SimPEG.Survey.BaseRx.__init__(self, locs, rxType=None) #TODO: remove rxType from baseRx
def projGLoc(self, u):
"""Grid Location projection (e.g. Ex Fy ...)"""
return u._GLoc(self.projField) + self.projComp
def eval(self, src, mesh, f):
"""
Project fields to recievers to get data.
:param Source src: FDEM source
:param Mesh mesh: mesh used
:param Fields f: fields object
:rtype: numpy.ndarray
:return: fields projected to recievers
"""
P = self.getP(mesh, self.projGLoc(f))
f_part_complex = f[src, self.projField]
f_part = getattr(f_part_complex, self.real_or_imag) # get the real or imag component
return P*f_part
def evalDeriv(self, src, mesh, f, v, adjoint=False):
"""
Derivative of projected fields with respect to the inversion model times a vector.
:param Source src: FDEM source
:param Mesh mesh: mesh used
:param Fields f: fields object
:param numpy.ndarray v: vector to multiply
:rtype: numpy.ndarray
:return: fields projected to recievers
"""
P = self.getP(mesh, self.projGLoc(f))
if not adjoint:
Pv_complex = P * v
Pv = getattr(Pv_complex, self.real_or_imag)
elif adjoint:
Pv_real = P.T * v
if self.real_or_imag == 'imag':
Pv = 1j*Pv_real
elif self.real_or_imag == 'real':
Pv = Pv_real.astype(complex)
else:
raise NotImplementedError('must be real or imag')
return Pv
class eField(BaseRx):
"""
Electric field FDEM receiver
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string real_or_imag: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, real_or_imag=None):
self.projField = 'e'
BaseRx.__init__(self, locs, orientation, real_or_imag)
class bField(BaseRx):
"""
Magnetic flux FDEM receiver
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string real_or_imag: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, real_or_imag=None):
self.projField = 'b'
BaseRx.__init__(self, locs, orientation, real_or_imag)
class hField(BaseRx):
"""
Magnetic field FDEM receiver
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string real_or_imag: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, real_or_imag=None):
self.projField = 'h'
BaseRx.__init__(self, locs, orientation, real_or_imag)
class jField(BaseRx):
"""
Current density FDEM receiver
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string real_or_imag: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, real_or_imag=None):
self.projField = 'j'
BaseRx.__init__(self, locs, orientation, real_or_imag)