$\renewcommand{\div}{\nabla\cdot\,} \newcommand{\grad}{\vec \nabla} \newcommand{\curl}{{\vec \nabla}\times\,}$

Frequency Domain Electromagnetics¶

Electromagnetic (EM) geophysical methods are used in a variety of applications from resource exploration, including for hydrocarbons and minerals, to environmental applications, such as groundwater monitoring. The primary physical property of interest in EM is electrical conductivity, which describes the ease with which electric current flows through a material.

Background¶

Electromagnetic phenomena are governed by Maxwell’s equations. They describe the behavior of EM fields and fluxes. Electromagnetic theory for geophysical applications by Ward and Hohmann (1988) is a highly recommended resource on this topic.

Fourier Transform Convention¶

In order to examine Maxwell’s equations in the frequency domain, we must first define our choice of harmonic time-dependence by choosing a Fourier transform convention. We use the $$e^{i \omega t}$$ convention, so we define our Fourier Transform pair as

\begin{align}\begin{aligned}\begin{split}F(\omega) = \int_{-\infty}^{\infty} f(t) e^{- i \omega t} dt \\\end{split}\\f(t) = \frac{1}{2\pi}\int_{-\infty}^{\infty} F(\omega) e^{i \omega t} d \omega\end{aligned}\end{align}

where $$\omega$$ is angular frequency, $$t$$ is time, $$F(\omega)$$ is the function defined in the frequency domain and $$f(t)$$ is the function defined in the time domain.

Maxwell’s Equations¶

In the frequency domain, Maxwell’s equations are given by

\begin{align}\begin{aligned}\begin{split}\curl \vec{E} + i \omega \vec{B} = \vec{S_m}\\\end{split}\\\begin{split}\curl \vec{H} - \vec{J} - i \omega \vec{D} = \vec{S_e} \\\end{split}\\\begin{split}\div \vec{B} = 0 \\\end{split}\\\div \vec{D} = \rho_f\end{aligned}\end{align}

where:

• $$\vec{E}$$ : electric field ($$V/m$$ )
• $$\vec{H}$$ : magnetic field ($$A/m$$ )
• $$\vec{B}$$ : magnetic flux density ($$Wb/m^2$$ )
• $$\vec{D}$$ : electric displacement / electric flux density ($$C/m^2$$ )
• $$\vec{J}$$ : electric current density ($$A/m^2$$ )
• $$\vec{S_m}$$ : magnetic source term ($$V/m^2$$ )
• $$\vec{S_e}$$ : electric source term ($$A/m^2$$ )
• $$\rho_f$$ : free charge density ($$\Omega m$$ )

Constitutive Relations¶

The fields and fluxes are related through the constitutive relations. At each frequency, they are given by

\begin{align}\begin{aligned}\begin{split}\vec{J} = \sigma \vec{E} \\\end{split}\\\begin{split}\vec{B} = \mu \vec{H} \\\end{split}\\\vec{D} = \varepsilon \vec{E}\end{aligned}\end{align}

where:

• $$\sigma$$ : electrical conductivity ($$S/m$$)
• $$\mu$$ : magnetic permeability ($$H/m$$)
• $$\varepsilon$$ : dielectric permittivity ($$F/m$$)

$$\sigma$$, $$\mu$$, $$\varepsilon$$ are physical properties which depend on the material. $$\sigma$$ describes how easily electric current passes through a material, $$\mu$$ describes how easily a material is magnetized, and $$\varepsilon$$ describes how easily a material is electrically polarized. In most low-frequency geophysical applications of EM, $$\sigma$$ is the primary physical property of interest, and $$\mu$$, $$\varepsilon$$ are assumed to have their free-space values $$\mu_0 = 4\pi \times 10^{-7} H/m$$ , $$\varepsilon_0 = 1/(\mu_0 c^2) \approx 8.85 \times 10^{-12} F/m$$, where $$c$$ is the speed of light in free space.

Quasi-static Approximation¶

For the frequency range typical of most geophysical surveys, the contribution of the electric displacement is negligible compared to the electric current density. In this case, we use the quasi-static approximation and assume that this term can be neglected, giving

$\begin{split}\nabla \times \vec{E} + i \omega \vec{B} = \vec{S_m} \\ \nabla \times \vec{H} - \vec{J} = \vec{S_e}\end{split}$

Geophysical methods where the quasi-static approximation, often called diffusive approximation, does not hold are high-frequency methods such as ground-penetrating radar or dielectric well-log measurements.

Implementation in SimPEG.EM¶

We consider two formulations in SimPEG.EM, both first-order and both in terms of one field and one flux. We allow for the definition of magnetic and electric sources (see for example: Ward and Hohmann, starting on page 144). The E-B formulation is in terms of the electric field and the magnetic flux:

$\begin{split}\nabla \times \vec{E} + i \omega \vec{B} = \vec{S}_m \\ \nabla \times \mu^{-1} \vec{B} - \sigma \vec{E} = \vec{S}_e\end{split}$

The H-J formulation is in terms of the current density and the magnetic field:

$\begin{split}\nabla \times \sigma^{-1} \vec{J} + i \omega \mu \vec{H} = \vec{S}_m \\ \nabla \times \vec{H} - \vec{J} = \vec{S}_e\end{split}$

Discretizing¶

For both formulations, we use a finite volume discretization and discretize fields on cell edges, fluxes on cell faces and physical properties in cell centers. This is particularly important when using symmetry to reduce the dimensionality of a problem (for instance on a 2D CylMesh, there are $$r$$, $$z$$ faces and $$\theta$$ edges)

For the two formulations, the discretization of the physical properties, fields and fluxes are summarized below.

Note that resistivity is the inverse of conductivity, $$\rho = \sigma^{-1}$$.

E-B Formulation¶

$\begin{split}\mathbf{C} \mathbf{e} + i \omega \mathbf{b} = \mathbf{s_m} \\ \mathbf{C^T} \mathbf{M^f_{\mu^{-1}}} \mathbf{b} - \mathbf{M^e_\sigma} \mathbf{e} = \mathbf{M^e} \mathbf{s_e}\end{split}$

H-J Formulation¶

$\begin{split}\mathbf{C^T} \mathbf{M^f_\rho} \mathbf{j} + i \omega \mathbf{M^e_\mu} \mathbf{h} = \mathbf{M^e} \mathbf{s_m} \\ \mathbf{C} \mathbf{h} - \mathbf{j} = \mathbf{s_e}\end{split}$

API¶

FDEM Problem¶

class SimPEG.EM.FDEM.ProblemFDEM.BaseFDEMProblem(mesh, **kwargs)

We start by looking at Maxwell’s equations in the electric field $$\mathbf{e}$$ and the magnetic flux density $$\mathbf{b}$$

$\begin{split}\mathbf{C} \mathbf{e} + i \omega \mathbf{b} = \mathbf{s_m} \\ {\mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{M_{\sigma}^e} \mathbf{e} = \mathbf{s_e}}\end{split}$

if using the E-B formulation (Problem3D_e or Problem3D_b). Note that in this case, $$\mathbf{s_e}$$ is an integrated quantity.

If we write Maxwell’s equations in terms of $$\mathbf{h}$$ and current density $$\mathbf{j}$$

$\begin{split}\mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{j} + i \omega \mathbf{M_{\mu}^e} \mathbf{h} = \mathbf{s_m} \\ \mathbf{C} \mathbf{h} - \mathbf{j} = \mathbf{s_e}\end{split}$

if using the H-J formulation (Problem3D_j or Problem3D_h). Note that here, $$\mathbf{s_m}$$ is an integrated quantity.

The problem performs the elimination so that we are solving the system for $$\mathbf{e},\mathbf{b},\mathbf{j}$$ or $$\mathbf{h}$$

Optional Properties:

Other Properties:

Jtvec(m, v, f=None)

Sensitivity transpose times a vector

Parameters: m (numpy.ndarray) – inversion model (nP,) v (numpy.ndarray) – vector which we take adjoint product with (nP,) u (SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM) – fields object numpy.ndarray Jv (ndata,)
Jvec(m, v, f=None)

Sensitivity times a vector.

Parameters: m (numpy.ndarray) – inversion model (nP,) v (numpy.ndarray) – vector which we take sensitivity product with (nP,) u (SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM) – fields object numpy.ndarray Jv (ndata,)
fields(m=None)

Solve the forward problem for the fields.

Parameters: m (numpy.ndarray) – inversion model (nP,) numpy.ndarray forward solution
fieldsPair

alias of FieldsFDEM

getSourceTerm(freq)

Evaluates the sources for a given frequency and puts them in matrix form

Parameters: freq (float) – Frequency tuple (s_m, s_e) (nE or nF, nSrc)
mu

Magnetic Permeability (H/m)

muDeriv

Derivative of Magnetic Permeability (H/m) wrt the model.

muMap

Mapping of Magnetic Permeability (H/m) to the inversion model.

mui

Inverse Magnetic Permeability (m/H)

muiDeriv

Derivative of Inverse Magnetic Permeability (m/H) wrt the model.

muiMap

Mapping of Inverse Magnetic Permeability (m/H) to the inversion model.

surveyPair

alias of Survey

class SimPEG.EM.FDEM.ProblemFDEM.Problem3D_b(mesh, **kwargs)

We eliminate $$\mathbf{e}$$ using

$\mathbf{e} = \mathbf{M^e_{\sigma}}^{-1} \left(\mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{s_e}\right)$

and solve for $$\mathbf{b}$$ using:

$\left(\mathbf{C} \mathbf{M^e_{\sigma}}^{-1} \mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} + i \omega \right)\mathbf{b} = \mathbf{s_m} + \mathbf{M^e_{\sigma}}^{-1}\mathbf{M^e}\mathbf{s_e}$

Note

The inverse problem will not work with full anisotropy

param discretize.base.BaseMesh mesh:
mesh

Optional Properties:

Other Properties:

fieldsPair

alias of Fields3D_b

getA(freq)

System matrix

$\mathbf{A} = \mathbf{C} \mathbf{M^e_{\sigma}}^{-1} \mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} + i \omega$
Parameters: freq (float) – Frequency scipy.sparse.csr_matrix A
getADeriv(freq, u, v, adjoint=False)
getADeriv_mui(freq, u, v, adjoint=False)
getADeriv_sigma(freq, u, v, adjoint=False)

Product of the derivative of our system matrix with respect to the model and a vector

$\frac{\mathbf{A}(\mathbf{m}) \mathbf{v}}{d \mathbf{m}} = \mathbf{C} \frac{\mathbf{M^e_{\sigma}} \mathbf{v}}{d\mathbf{m}}$
Parameters: freq (float) – frequency u (numpy.ndarray) – solution vector (nF,) v (numpy.ndarray) – vector to take prodct with (nP,) or (nD,) for adjoint adjoint (bool) – adjoint? numpy.ndarray derivative of the system matrix times a vector (nP,) or adjoint (nD,)
getRHS(freq)

Right hand side for the system

$\mathbf{RHS} = \mathbf{s_m} + \mathbf{M^e_{\sigma}}^{-1}\mathbf{s_e}$
Parameters: freq (float) – Frequency numpy.ndarray RHS (nE, nSrc)
getRHSDeriv(freq, src, v, adjoint=False)

Derivative of the right hand side with respect to the model

Parameters: freq (float) – frequency src (SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc) – FDEM source v (numpy.ndarray) – vector to take product with adjoint (bool) – adjoint? numpy.ndarray product of rhs deriv with a vector
class SimPEG.EM.FDEM.ProblemFDEM.Problem3D_e(mesh, **kwargs)

By eliminating the magnetic flux density using

$\mathbf{b} = \frac{1}{i \omega}\left(-\mathbf{C} \mathbf{e} + \mathbf{s_m}\right)$

we can write Maxwell’s equations as a second order system in $$\mathbf{e}$$ only:

$\left(\mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{C} + i \omega \mathbf{M^e_{\sigma}} \right)\mathbf{e} = \mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f}\mathbf{s_m} - i\omega\mathbf{M^e}\mathbf{s_e}$

which we solve for $$\mathbf{e}$$.

param discretize.base.BaseMesh mesh:
mesh

Optional Properties:

Other Properties:

fieldsPair

alias of Fields3D_e

getA(freq)

System matrix

$\mathbf{A} = \mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{C} + i \omega \mathbf{M^e_{\sigma}}$
Parameters: freq (float) – Frequency scipy.sparse.csr_matrix A
getADeriv(freq, u, v, adjoint=False)
getADeriv_mui(freq, u, v, adjoint=False)

Product of the derivative of the system matrix with respect to the permeability model and a vector.

$\frac{\mathbf{A}(\mathbf{m}) \mathbf{v}}{d \mathbf{m}_{\mu^{-1}} = \mathbf{C}^{ op} \frac{d \mathbf{M^f_{\mu^{-1}}}\mathbf{v}}{d\mathbf{m}}$
getADeriv_sigma(freq, u, v, adjoint=False)

Product of the derivative of our system matrix with respect to the conductivity model and a vector

$\frac{\mathbf{A}(\mathbf{m}) \mathbf{v}}{d \mathbf{m}_{\sigma}} = i \omega \frac{d \mathbf{M^e_{\sigma}}(\mathbf{u})\mathbf{v} }{d\mathbf{m}}$
Parameters: freq (float) – frequency u (numpy.ndarray) – solution vector (nE,) v (numpy.ndarray) – vector to take prodct with (nP,) or (nD,) for adjoint adjoint (bool) – adjoint? numpy.ndarray derivative of the system matrix times a vector (nP,) or adjoint (nD,)
getRHS(freq)

Right hand side for the system

$\mathbf{RHS} = \mathbf{C}^{\top} \mathbf{M_{\mu^{-1}}^f}\mathbf{s_m} - i\omega\mathbf{M_e}\mathbf{s_e}$
Parameters: freq (float) – Frequency numpy.ndarray RHS (nE, nSrc)
getRHSDeriv(freq, src, v, adjoint=False)

Derivative of the Right-hand side with respect to the model. This includes calls to derivatives in the sources

class SimPEG.EM.FDEM.ProblemFDEM.Problem3D_h(mesh, **kwargs)

We eliminate $$\mathbf{j}$$ using

$\mathbf{j} = \mathbf{C} \mathbf{h} - \mathbf{s_e}$

and solve for $$\mathbf{h}$$ using

$\left(\mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}\right) \mathbf{h} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{s_e}$
param discretize.base.BaseMesh mesh:
mesh

Optional Properties:

Other Properties:

fieldsPair

alias of Fields3D_h

getA(freq)

System matrix

$\mathbf{A} = \mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}$
Parameters: freq (float) – Frequency scipy.sparse.csr_matrix A
getADeriv(freq, u, v, adjoint=False)
getADeriv_mu(freq, u, v, adjoint=False)
getADeriv_rho(freq, u, v, adjoint=False)

Product of the derivative of our system matrix with respect to the model and a vector

$\frac{\mathbf{A}(\mathbf{m}) \mathbf{v}}{d \mathbf{m}} = \mathbf{C}^{\top}\frac{d \mathbf{M^f_{\rho}}\mathbf{v}} {d\mathbf{m}}$
Parameters: freq (float) – frequency u (numpy.ndarray) – solution vector (nE,) v (numpy.ndarray) – vector to take prodct with (nP,) or (nD,) for adjoint adjoint (bool) – adjoint? numpy.ndarray derivative of the system matrix times a vector (nP,) or adjoint (nD,)
getRHS(freq)

Right hand side for the system

$\mathbf{RHS} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{s_e}$
Parameters: freq (float) – Frequency numpy.ndarray RHS (nE, nSrc)
getRHSDeriv(freq, src, v, adjoint=False)

Derivative of the right hand side with respect to the model

Parameters: freq (float) – frequency src (SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc) – FDEM source v (numpy.ndarray) – vector to take product with adjoint (bool) – adjoint? numpy.ndarray product of rhs deriv with a vector
class SimPEG.EM.FDEM.ProblemFDEM.Problem3D_j(mesh, **kwargs)

We eliminate $$\mathbf{h}$$ using

$\mathbf{h} = \frac{1}{i \omega} \mathbf{M_{\mu}^e}^{-1} \left(-\mathbf{C}^{\top} \mathbf{M_{\rho}^f} \mathbf{j} + \mathbf{M^e} \mathbf{s_m} \right)$

and solve for $$\mathbf{j}$$ using

$\left(\mathbf{C} \mathbf{M_{\mu}^e}^{-1} \mathbf{C}^{\top} \mathbf{M_{\rho}^f} + i \omega\right)\mathbf{j} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1} \mathbf{M^e} \mathbf{s_m} - i\omega\mathbf{s_e}$

Note

This implementation does not yet work with full anisotropy!!

param discretize.base.BaseMesh mesh:
mesh

Optional Properties:

Other Properties:

fieldsPair

alias of Fields3D_j

getA(freq)

System matrix

$\mathbf{A} = \mathbf{C} \mathbf{M^e_{\mu^{-1}}} \mathbf{C}^{\top} \mathbf{M^f_{\sigma^{-1}}} + i\omega$
Parameters: freq (float) – Frequency scipy.sparse.csr_matrix A
getADeriv(freq, u, v, adjoint=False)
getADeriv_mu(freq, u, v, adjoint=False)
getADeriv_rho(freq, u, v, adjoint=False)

Product of the derivative of our system matrix with respect to the model and a vector

In this case, we assume that electrical conductivity, $$\sigma$$ is the physical property of interest (i.e. $$\sigma$$ = model.transform). Then we want

$\frac{\mathbf{A(\sigma)} \mathbf{v}}{d \mathbf{m}} = \mathbf{C} \mathbf{M^e_{mu^{-1}}} \mathbf{C^{\top}} \frac{d \mathbf{M^f_{\sigma^{-1}}}\mathbf{v} }{d \mathbf{m}}$
Parameters: freq (float) – frequency u (numpy.ndarray) – solution vector (nF,) v (numpy.ndarray) – vector to take prodct with (nP,) or (nD,) for adjoint adjoint (bool) – adjoint? numpy.ndarray derivative of the system matrix times a vector (nP,) or adjoint (nD,)
getRHS(freq)

Right hand side for the system

$\mathbf{RHS} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1}\mathbf{s_m} - i\omega \mathbf{s_e}$
Parameters: freq (float) – Frequency numpy.ndarray RHS (nE, nSrc)
getRHSDeriv(freq, src, v, adjoint=False)

Derivative of the right hand side with respect to the model

Parameters: freq (float) – frequency src (SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc) – FDEM source v (numpy.ndarray) – vector to take product with adjoint (bool) – adjoint? numpy.ndarray product of rhs deriv with a vector

FDEM Survey¶

class SimPEG.EM.FDEM.SurveyFDEM.Survey(srcList, **kwargs)

Frequency domain electromagnetic survey

Parameters: srcList (list) – list of FDEM sources used in the survey
freqs

Frequencies

getSrcByFreq(freq)

Returns the sources associated with a specific frequency. :param float freq: frequency for which we look up sources :rtype: dictionary :return: sources at the sepcified frequency

nFreq

Number of frequencies

nSrcByFreq

Number of sources at each frequency

rxPair

alias of BaseRx

srcPair

alias of BaseFDEMSrc

class SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc(rxList, **kwargs)
Base source class for FDEM Survey

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
bPrimary(prob)

Primary magnetic flux density

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray primary magnetic flux density
bPrimaryDeriv(prob, v, adjoint=False)

Derivative of the primary magnetic flux density

Parameters: prob (BaseFDEMProblem) – FDEM Problem v (numpy.ndarray) – vector adjoint (bool) – adjoint? numpy.ndarray primary magnetic flux density
ePrimary(prob)

Primary electric field

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray primary electric field
ePrimaryDeriv(prob, v, adjoint=False)

Derivative of the primary electric field

Parameters: prob (BaseFDEMProblem) – FDEM Problem v (numpy.ndarray) – vector adjoint (bool) – adjoint? numpy.ndarray primary magnetic flux density
freq

freq (Float): frequency of the source, a float in range [0, inf]

hPrimary(prob)

Primary magnetic field

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray primary magnetic field
hPrimaryDeriv(prob, v, adjoint=False)

Derivative of the primary magnetic field

Parameters: prob (BaseFDEMProblem) – FDEM Problem v (numpy.ndarray) – vector adjoint (bool) – adjoint? numpy.ndarray primary magnetic flux density
jPrimary(prob)

Primary current density

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray primary current density
jPrimaryDeriv(prob, v, adjoint=False)

Derivative of the primary current density

Parameters: prob (BaseFDEMProblem) – FDEM Problem v (numpy.ndarray) – vector adjoint (bool) – adjoint? numpy.ndarray primary magnetic flux density
class SimPEG.EM.FDEM.SrcFDEM.CircularLoop(rxList, freq, loc, **kwargs)

Circular loop magnetic source calculated by taking the curl of a magnetic vector potential. By taking the discrete curl, we ensure that the magnetic flux density is divergence free (no magnetic monopoles!).

This approach uses a primary-secondary in frequency in the same fashion as the MagDipole.

param list rxList:
param float freq:
frequency
param numpy.ndarray loc:
source location (ie: np.r_[xloc,yloc,zloc])
param string orientation:
‘X’, ‘Y’, ‘Z’
param float moment:
magnetic dipole moment
param float mu:background magnetic permeability

Required Properties:

• current (Float): current in the loop, a float, Default: 1.0
• freq (Float): frequency of the source (Hz), a float
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (LocationVector): location of the source, of <class ‘float’>, <class ‘int’> with shape (3), Default: [0. 0. 0.]
• mu (Float): permeability of the background, a float in range [0.0, inf], Default: 1.2566370614359173e-06
• orientation (Vector3): orientation of the source, a 3D Vector of <class ‘float’> with shape (3), Default: Z
• radius (Float): radius of the loop, a float in range [0.0, inf], Default: 1.0
current

current (Float): current in the loop, a float, Default: 1.0

moment
radius

radius (Float): radius of the loop, a float in range [0.0, inf], Default: 1.0

class SimPEG.EM.FDEM.SrcFDEM.MagDipole(rxList, freq, loc, **kwargs)

Point magnetic dipole source calculated by taking the curl of a magnetic vector potential. By taking the discrete curl, we ensure that the magnetic flux density is divergence free (no magnetic monopoles!).

This approach uses a primary-secondary in frequency. Here we show the derivation for E-B formulation noting that similar steps are followed for the H-J formulation.

$\begin{split}\mathbf{C} \mathbf{e} + i \omega \mathbf{b} = \mathbf{s_m} \\ {\mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{M_{\sigma}^e} \mathbf{e} = \mathbf{s_e}}\end{split}$

We split up the fields and $$\mu^{-1}$$ into primary ($$\mathbf{P}$$) and secondary ($$\mathbf{S}$$) components

• $$\mathbf{e} = \mathbf{e^P} + \mathbf{e^S}$$
• $$\mathbf{b} = \mathbf{b^P} + \mathbf{b^S}$$
• $$\boldsymbol{\mu}^{\mathbf{-1}} = \boldsymbol{\mu}^{\mathbf{-1}^\mathbf{P}} + \boldsymbol{\mu}^{\mathbf{-1}^\mathbf{S}}$$

and define a zero-frequency primary problem, noting that the source is generated by a divergence free electric current

$\begin{split}\mathbf{C} \mathbf{e^P} = \mathbf{s_m^P} = 0 \\ {\mathbf{C}^T \mathbf{{M_{\mu^{-1}}^f}^P} \mathbf{b^P} - \mathbf{M_{\sigma}^e} \mathbf{e^P} = \mathbf{M^e} \mathbf{s_e^P}}\end{split}$

Since $$\mathbf{e^P}$$ is curl-free, divergence-free, we assume that there is no constant field background, the $$\mathbf{e^P} = 0$$, so our primary problem is

$\begin{split}\mathbf{e^P} = 0 \\ {\mathbf{C}^T \mathbf{{M_{\mu^{-1}}^f}^P} \mathbf{b^P} = \mathbf{s_e^P}}\end{split}$

Our secondary problem is then

$\begin{split}\mathbf{C} \mathbf{e^S} + i \omega \mathbf{b^S} = - i \omega \mathbf{b^P} \\ {\mathbf{C}^T \mathbf{M_{\mu^{-1}}^f} \mathbf{b^S} - \mathbf{M_{\sigma}^e} \mathbf{e^S} = -\mathbf{C}^T \mathbf{{M_{\mu^{-1}}^f}^S} \mathbf{b^P}}\end{split}$
param list rxList:
param float freq:
frequency
param numpy.ndarray loc:
source location (ie: np.r_[xloc,yloc,zloc])
param string orientation:
‘X’, ‘Y’, ‘Z’
param float moment:
magnetic dipole moment
param float mu:background magnetic permeability

Required Properties:

• freq (Float): frequency of the source (Hz), a float
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (LocationVector): location of the source, of <class ‘float’>, <class ‘int’> with shape (3), Default: [0. 0. 0.]
• moment (Float): dipole moment of the transmitter, a float in range [0.0, inf], Default: 1.0
• mu (Float): permeability of the background, a float in range [0.0, inf], Default: 1.2566370614359173e-06
• orientation (Vector3): orientation of the source, a 3D Vector of <class ‘float’> with shape (3), Default: Z
bPrimary(prob)

The primary magnetic flux density from a magnetic vector potential

Parameters: prob (BaseFDEMProblem) – FDEM problem numpy.ndarray primary magnetic field
freq

freq (Float): frequency of the source (Hz), a float

hPrimary(prob)

The primary magnetic field from a magnetic vector potential

Parameters: prob (BaseFDEMProblem) – FDEM problem numpy.ndarray primary magnetic field
loc

loc (LocationVector): location of the source, of <class ‘float’>, <class ‘int’> with shape (3), Default: [0. 0. 0.]

moment

moment (Float): dipole moment of the transmitter, a float in range [0.0, inf], Default: 1.0

mu

mu (Float): permeability of the background, a float in range [0.0, inf], Default: 1.2566370614359173e-06

orientation

orientation (Vector3): orientation of the source, a 3D Vector of <class ‘float’> with shape (3), Default: Z

s_e(prob)

The electric source term

Parameters: prob (BaseFDEMProblem) – FDEM problem numpy.ndarray primary magnetic field
s_eDeriv(prob, v, adjoint=False)
s_m(prob)

The magnetic source term

Parameters: prob (BaseFDEMProblem) – FDEM problem numpy.ndarray primary magnetic field
class SimPEG.EM.FDEM.SrcFDEM.MagDipole_Bfield(rxList, freq, loc, **kwargs)

Point magnetic dipole source calculated with the analytic solution for the fields from a magnetic dipole. No discrete curl is taken, so the magnetic flux density may not be strictly divergence free.

This approach uses a primary-secondary in frequency in the same fashion as the MagDipole.

param list rxList:
param float freq:
frequency
param numpy.ndarray loc:
source location (ie: np.r_[xloc,yloc,zloc])
param string orientation:
‘X’, ‘Y’, ‘Z’
param float moment:
magnetic dipole moment
param float mu:background magnetic permeability

Required Properties:

• freq (Float): frequency of the source (Hz), a float
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (LocationVector): location of the source, of <class ‘float’>, <class ‘int’> with shape (3), Default: [0. 0. 0.]
• moment (Float): dipole moment of the transmitter, a float in range [0.0, inf], Default: 1.0
• mu (Float): permeability of the background, a float in range [0.0, inf], Default: 1.2566370614359173e-06
• orientation (Vector3): orientation of the source, a 3D Vector of <class ‘float’> with shape (3), Default: Z
bPrimary(prob)

The primary magnetic flux density from the analytic solution for magnetic fields from a dipole

Parameters: prob (BaseFDEMProblem) – FDEM problem numpy.ndarray primary magnetic field
class SimPEG.EM.FDEM.SrcFDEM.PrimSecMappedSigma(rxList, freq, primaryProblem, primarySurvey, map2meshSecondary=None, **kwargs)

Primary-Secondary Source in which a mapping is provided to put the current model onto the primary mesh. This is solved on every model update. There are a lot of layers to the derivatives here!

Required :param list rxList: Receiver List :param float freq: frequency :param BaseFDEMProblem primaryProblem: FDEM primary problem :param SurveyFDEM primarySurvey: FDEM primary survey

Optional :param Mapping map2meshSecondary: mapping current model to act as primary model on the secondary mesh

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
bPrimary(prob, f=None)
ePrimary(prob, f=None)
ePrimaryDeriv(prob, v, adjoint=False, f=None)
s_e(prob, f=None)
s_eDeriv(prob, v, adjoint=False)
class SimPEG.EM.FDEM.SrcFDEM.PrimSecSigma(rxList, freq, sigBack, ePrimary, **kwargs)

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
s_e(prob)
s_eDeriv(prob, v, adjoint=False)
class SimPEG.EM.FDEM.SrcFDEM.RawVec(rxList, freq, s_m, s_e, **kwargs)

RawVec source. It is defined by the user provided vectors s_m, s_e

param rxList: param float freq: receiver list frequency magnetic source term electric source term Integrate the source term (multiply by Me) [False]

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
s_e(prob)

Electric source term

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray electric source term on mesh
s_m(prob)

Magnetic source term

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray magnetic source term on mesh
class SimPEG.EM.FDEM.SrcFDEM.RawVec_e(rxList, freq, s_e, **kwargs)

RawVec electric source. It is defined by the user provided vector s_e

param list rxList:
param float freq:
frequency
param numpy.ndarray s_e:
electric source term
param bool integrate:
Integrate the source term (multiply by Me) [False]

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
s_e(prob)

Electric source term

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray electric source term on mesh
class SimPEG.EM.FDEM.SrcFDEM.RawVec_m(rxList, freq, s_m, **kwargs)

RawVec magnetic source. It is defined by the user provided vector s_m

param float freq:
frequency
param numpy.ndarray s_m:
magnetic source term
param bool integrate:
Integrate the source term (multiply by Me) [False]

Required Properties:

• freq (Float): frequency of the source, a float in range [0, inf]
• integrate (Boolean): integrate the source term?, a boolean, Default: False
• loc (Array): location of the source, a list or numpy array of <class ‘float’>, <class ‘int’> with shape (*, 3) or (3)
s_m(prob)

Magnetic source term

Parameters: prob (BaseFDEMProblem) – FDEM Problem numpy.ndarray magnetic source term on mesh
class SimPEG.EM.FDEM.RxFDEM.BaseRx(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’
eval(src, mesh, f)

Project fields to receivers to get data.

Parameters: src (SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc) – FDEM source mesh (discretize.base.BaseMesh) – mesh used f (Fields) – fields object numpy.ndarray fields projected to recievers
evalDeriv(src, mesh, f, du_dm_v=None, v=None, adjoint=False)

Derivative of projected fields with respect to the inversion model times a vector.

Parameters: src (SimPEG.EM.FDEM.SrcFDEM.BaseFDEMSrc) – FDEM source mesh (discretize.base.BaseMesh) – mesh used f (Fields) – fields object v (numpy.ndarray) – vector to multiply numpy.ndarray fields projected to recievers
projGLoc(f)

Grid Location projection (e.g. Ex Fy ...)

class SimPEG.EM.FDEM.RxFDEM.Point_b(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’
class SimPEG.EM.FDEM.RxFDEM.Point_bSecondary(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’
class SimPEG.EM.FDEM.RxFDEM.Point_e(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’
class SimPEG.EM.FDEM.RxFDEM.Point_h(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’
class SimPEG.EM.FDEM.RxFDEM.Point_j(locs, orientation=None, component=None)

Parameters: locs (numpy.ndarray) – receiver locations (ie. np.r_[x,y,z]) orientation (string) – receiver orientation ‘x’, ‘y’ or ‘z’ component (string) – real or imaginary component ‘real’ or ‘imag’

FDEM Fields¶

class SimPEG.EM.FDEM.FieldsFDEM.Fields3D_b(mesh, survey, **kwargs)

Fields object for Problem3D_b.

Parameters: mesh (discretize.base.BaseMesh) – mesh survey (SimPEG.EM.FDEM.SurveyFDEM.Survey) – survey
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'], 'j': ['bSolution', 'E', '_j'], 'h': ['bSolution', 'F', '_h']}
knownFields = {'bSolution': 'F'}
startup()
class SimPEG.EM.FDEM.FieldsFDEM.Fields3D_e(mesh, survey, **kwargs)

Fields object for Problem3D_e.

Parameters: mesh (discretize.base.BaseMesh) – mesh survey (SimPEG.EM.FDEM.SurveyFDEM.Survey) – survey
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'], 'j': ['eSolution', 'E', '_j'], 'h': ['eSolution', 'F', '_h']}
knownFields = {'eSolution': 'E'}
startup()
class SimPEG.EM.FDEM.FieldsFDEM.Fields3D_h(mesh, survey, **kwargs)

Fields object for Problem3D_h.

Parameters: mesh (discretize.base.BaseMesh) – mesh survey (SimPEG.EM.FDEM.SurveyFDEM.Survey) – survey
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'], 'e': ['hSolution', 'CCV', '_e'], 'b': ['hSolution', 'CCV', '_b']}
knownFields = {'hSolution': 'E'}
startup()
class SimPEG.EM.FDEM.FieldsFDEM.Fields3D_j(mesh, survey, **kwargs)

Fields object for Problem3D_j.

Parameters: mesh (discretize.base.BaseMesh) – mesh survey (SimPEG.EM.FDEM.SurveyFDEM.Survey) – survey
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'], 'e': ['jSolution', 'F', '_e'], 'b': ['jSolution', 'E', '_b']}
knownFields = {'jSolution': 'F'}
startup()
class SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM(mesh, survey, **kwargs)

Fancy Field Storage for a FDEM survey. Only one field type is stored for each problem, the rest are computed. The fields object acts like an array and is indexed by

f = problem.fields(m)
e = f[srcList,'e']
b = f[srcList,'b']


If accessing all sources for a given field, use the :

f = problem.fields(m)
e = f[:,'e']
b = f[:,'b']


The array returned will be size (nE or nF, nSrcs $$\times$$ nFrequencies)

dtype

alias of complex

knownFields = {}