mirror of
https://github.com/wassname/simpeg.git
synced 2026-07-12 20:09:10 +08:00
organizing the docs - put the content in a content folder. put the SimPEG core api docs in core_api
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
.. _api_DataMisfit:
|
||||
|
||||
|
||||
Data Misfit
|
||||
***********
|
||||
|
||||
The data misfit using an l_2 norm is:
|
||||
|
||||
.. math::
|
||||
|
||||
\mu_\text{data} = {1\over 2}\left| \mathbf{W}_d (\mathbf{d}_\text{pred} - \mathbf{d}_\text{obs}) \right|_2^2
|
||||
|
||||
If the field, u, is provided, the calculation of the data is fast:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_\text{pred} = \mathbf{Pu(m)}
|
||||
|
||||
\mathbf{R} = \mathbf{W}_d (\mathbf{d}_\text{pred} - \mathbf{d}_\text{obs})
|
||||
|
||||
Where P is a projection matrix that brings the field on the full domain to the data measurement locations;
|
||||
u is the field of interest; d_obs is the observed data; and \\\(\\mathbf{W}_d\\\) is the weighting matrix.
|
||||
|
||||
The derivative of this, with respect to the model, is:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \mu_\text{data}}{\partial \mathbf{m}} = \mathbf{J}^\top \mathbf{W}_d \mathbf{R}
|
||||
|
||||
The second derivative is:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial^2 \mu_\text{data}}{\partial^2 \mathbf{m}} = \mathbf{J}^\top \mathbf{W}_d \mathbf{W}_d \mathbf{J}
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
.. autoclass:: SimPEG.DataMisfit.BaseDataMisfit
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Common Data Misfits
|
||||
===================
|
||||
|
||||
l2 norm
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.DataMisfit.l2_DataMisfit
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,8 @@
|
||||
.. _api_DiffOps:
|
||||
|
||||
Differential Operators
|
||||
======================
|
||||
|
||||
.. automodule:: SimPEG.Mesh.DiffOperators
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,18 @@
|
||||
.. _api_Examples:
|
||||
|
||||
Examples
|
||||
********
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:glob:
|
||||
|
||||
../examples/*
|
||||
|
||||
|
||||
External Notebooks
|
||||
==================
|
||||
|
||||
* `Example 1: Direct Current <http://www.seogi.me/s/notebooks/DCEx.html>`_
|
||||
* `Example 2: Seismic-Acoustic <http://www.seogi.me/s/notebooks/SeismicEx.html>`_
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
.. _api_FiniteVolume:
|
||||
|
||||
Finite Volume
|
||||
*************
|
||||
|
||||
Any numerical implementation requires the discretization of continuous
|
||||
functions into discrete approximations. These approximations are typically
|
||||
organized in a mesh, which defines boundaries, locations, and connectivity. Of
|
||||
specific interest to geophysical simulations, we require that averaging,
|
||||
interpolation and differential operators be defined for any mesh. In SimPEG,
|
||||
we have implemented a staggered mimetic finite volume approach (`Hyman and
|
||||
Shashkov, 1999 <http://math.lanl.gov/~mac/papers/numerics/HS99B.pdf>`_). This
|
||||
approach requires the definitions of variables at either cell-centers, nodes,
|
||||
faces, or edges as seen in the figure below.
|
||||
|
||||
.. image:: ../../images/finitevolrealestate.png
|
||||
:width: 400 px
|
||||
:alt: FiniteVolume
|
||||
:align: center
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_Mesh
|
||||
api_DiffOps
|
||||
api_InnerProducts
|
||||
@@ -0,0 +1,113 @@
|
||||
.. _api_ForwardProblem:
|
||||
|
||||
|
||||
Forward Problem
|
||||
***************
|
||||
|
||||
Problem Class
|
||||
=============
|
||||
|
||||
The problem is a partial differential equation of the form:
|
||||
|
||||
.. math::
|
||||
|
||||
c(m, u) = 0
|
||||
|
||||
Here, \\(m\\) is the model and u is the field (or fields).
|
||||
Given the model, \\(m\\), we can calculate the fields \\(u(m)\\),
|
||||
however, the data we collect is a subset of the fields,
|
||||
and can be defined by a linear projection, \\(P\\).
|
||||
|
||||
.. math::
|
||||
|
||||
d_\text{pred} = P u(m)
|
||||
|
||||
For the inverse problem, we are interested in how changing the model transforms the data,
|
||||
as such we can take write the Taylor expansion:
|
||||
|
||||
.. math::
|
||||
|
||||
Pu(m + hv) = Pu(m) + hP\frac{\partial u(m)}{\partial m} v + \mathcal{O}(h^2 \left\| v \right\| )
|
||||
|
||||
We can linearize and define the sensitivity matrix as:
|
||||
|
||||
.. math::
|
||||
|
||||
J = P\frac{\partial u}{\partial m}
|
||||
|
||||
The sensitivity matrix, and it's transpose will be used in the inverse problem
|
||||
to (locally) find how model parameters change the data, and optimize!
|
||||
|
||||
|
||||
Working with the general PDE, \\(c(m, u) = 0\\), where m is the model and u is the field,
|
||||
the sensitivity is defined as:
|
||||
|
||||
.. math::
|
||||
|
||||
J = P\frac{\partial u}{\partial m}
|
||||
|
||||
We can take the derivative of the PDE:
|
||||
|
||||
.. math::
|
||||
|
||||
\nabla_m c(m, u) \partial m + \nabla_u c(m, u) \partial u = 0
|
||||
|
||||
If the forward problem is invertible, then we can rearrange for
|
||||
\\(\\frac{\\partial u}{\\partial m}\\):
|
||||
|
||||
.. math::
|
||||
|
||||
J = - P \left( \nabla_u c(m, u) \right)^{-1} \nabla_m c(m, u)
|
||||
|
||||
This can often be computed given a vector (i.e. \\(J(v)\\)) rather than
|
||||
stored, as \\(J\\) is a large dense matrix.
|
||||
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
Problem
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.Problem.BaseProblem
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Problem.BaseTimeProblem
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
.. autoclass:: SimPEG.Fields.Fields
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Fields.TimeFields
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Survey
|
||||
------
|
||||
|
||||
.. autoclass:: SimPEG.Survey.BaseSurvey
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Survey.BaseSrc
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Survey.BaseRx
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Survey.BaseTimeRx
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. autoclass:: SimPEG.Survey.Data
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,301 @@
|
||||
.. _api_InnerProducts:
|
||||
|
||||
|
||||
Inner Products
|
||||
**************
|
||||
|
||||
By using the weak formulation of many of the PDEs in geophysical applications,
|
||||
we can rapidly develop discretizations. Much of this work, however, needs a
|
||||
good understanding of how to approximate inner products on our discretized
|
||||
meshes. We will define the inner product as:
|
||||
|
||||
.. math::
|
||||
|
||||
\left(a,b\right) = \int_\Omega{a \cdot b}{\partial v}
|
||||
|
||||
where a and b are either scalars or vectors.
|
||||
|
||||
.. note::
|
||||
|
||||
The InnerProducts class is a base class providing inner product matrices
|
||||
for meshes and cannot run on its own.
|
||||
|
||||
|
||||
Example problem for DC resistivity
|
||||
----------------------------------
|
||||
|
||||
We will start with the formulation of the Direct Current (DC) resistivity
|
||||
problem in geophysics.
|
||||
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{1}{\sigma}\vec{j} = \nabla \phi \\
|
||||
|
||||
\nabla\cdot \vec{j} = q
|
||||
|
||||
In the following discretization, :math:`\sigma` and :math:`\phi`
|
||||
will be discretized on the cell-centers and the flux, :math:`\vec{j}`,
|
||||
will be on the faces. We will use the weak formulation to discretize
|
||||
the DC resistivity equation.
|
||||
|
||||
We can define in weak form by integrating with a general face function
|
||||
:math:`\vec{f}`:
|
||||
|
||||
.. math::
|
||||
|
||||
\int_{\Omega}{\sigma^{-1}\vec{j} \cdot \vec{f}} = \int_{\Omega}{\nabla \phi \cdot \vec{f}}
|
||||
|
||||
Here we can integrate the right side by parts,
|
||||
|
||||
.. math::
|
||||
|
||||
\nabla\cdot(\phi\vec{f})=\nabla\phi\cdot\vec{f} + \phi\nabla\cdot\vec{f}
|
||||
|
||||
and rearrange it, and apply the Divergence theorem.
|
||||
|
||||
.. math::
|
||||
|
||||
\int_{\Omega}{\sigma^{-1}\vec{j} \cdot \vec{f}} =
|
||||
- \int_{\Omega}{(\phi \nabla \cdot \vec{f})}
|
||||
+ \int_{\partial \Omega}{ \phi \vec{f} \cdot \mathbf{n}}
|
||||
|
||||
We can then discretize for every cell:
|
||||
|
||||
.. math::
|
||||
|
||||
v_{\text{cell}} \sigma^{-1} (\mathbf{J}_x \mathbf{F}_x +\mathbf{J}_y \mathbf{F}_y + \mathbf{J}_z \mathbf{F}_z ) = -\phi^{\top} v_{\text{cell}} \mathbf{D}_{\text{cell}} \mathbf{F} + \text{BC}
|
||||
|
||||
.. note::
|
||||
|
||||
We have discretized the dot product above, but remember that we do not
|
||||
really have a single vector :math:`\mathbf{J}`, but approximations of
|
||||
:math:`\vec{j}` on each face of our cell. In 2D that means 2
|
||||
approximations of :math:`\mathbf{J}_x` and 2 approximations of
|
||||
:math:`\mathbf{J}_y`. In 3D we also have 2 approximations of
|
||||
:math:`\mathbf{J}_z`.
|
||||
|
||||
Regardless of how we choose to approximate this dot product, we can represent
|
||||
this in vector form (again this is for every cell), and will generalize for
|
||||
the case of anisotropic (tensor) sigma.
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}_c^{\top} (\sqrt{v_{\text{cell}}} \Sigma^{-1} \sqrt{v_{\text{cell}}}) \mathbf{J}_c =
|
||||
-\phi^{\top} v_{\text{cell}} \mathbf{D}_{\text{cell}} \mathbf{F})
|
||||
+ \text{BC}
|
||||
|
||||
We multiply by square-root of volume on each side of the tensor conductivity
|
||||
to keep symmetry in the system. Here :math:`\mathbf{J}_c` is the Cartesian
|
||||
:math:`\mathbf{J}` (on the faces that we choose to use in our approximation)
|
||||
and must be calculated differently depending on the mesh:
|
||||
|
||||
.. math::
|
||||
\mathbf{J}_c = \mathbf{Q}_{(i)}\mathbf{J}_\text{TENSOR} \\
|
||||
\mathbf{J}_c = \mathbf{N}_{(i)}^{-1}\mathbf{Q}_{(i)}\mathbf{J}_\text{Curv}
|
||||
|
||||
Here the :math:`i` index refers to where we choose to approximate this integral, as discussed in the note above.
|
||||
We will approximate this integral by taking the fluxes clustered around every node of the cell, there are 8 combinations in 3D, and 4 in 2D. We will use a projection matrix :math:`\mathbf{Q}_{(i)}` to pick the appropriate fluxes. So, now that we have 8 approximations of this integral, we will just take the average. For the TensorMesh, this looks like:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{F}^{\top}
|
||||
{1\over 8}
|
||||
\left(\sum_{i=1}^8
|
||||
\mathbf{Q}_{(i)}^{\top} \sqrt{v_{\text{cell}}} \Sigma^{-1} \sqrt{v_{\text{cell}}} \mathbf{Q}_{(i)}
|
||||
\right)
|
||||
\mathbf{J}
|
||||
=
|
||||
-\mathbf{F}^{\top} \mathbf{D}_{\text{cell}}^{\top} v_{\text{cell}} \phi + \text{BC}
|
||||
|
||||
Or, when generalizing to the entire mesh and dropping our general face function:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{M}^f_{\Sigma^{-1}} \mathbf{J}
|
||||
=
|
||||
- \mathbf{D}^{\top} \text{diag}(\mathbf{v}) \phi + \text{BC}
|
||||
|
||||
By defining the faceInnerProduct (8 combinations of fluxes in 3D, 4 in 2D, 2 in 1D) to be:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{M}^f_{\Sigma^{-1}} =
|
||||
\sum_{i=1}^{2^d}
|
||||
\mathbf{P}_{(i)}^{\top} \Sigma^{-1} \mathbf{P}_{(i)}
|
||||
|
||||
Where :math:`d` is the dimension of the mesh.
|
||||
The :math:`\mathbf{M}^f` is returned when given the input of :math:`\Sigma^{-1}`.
|
||||
|
||||
Here each :math:`\mathbf{P} ~ \in ~ \mathbb{R}^{(d*nC, nF)}` is a combination
|
||||
of the projection, volume, and any normalization to Cartesian coordinates
|
||||
(where the dot product is well defined):
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{P}_{(i)} = \sqrt{ \frac{1}{2^d} \mathbf{I}^d \otimes \text{diag}(\mathbf{v})} \overbrace{\mathbf{N}_{(i)}^{-1}}^{\text{Curv only}} \mathbf{Q}_{(i)}
|
||||
|
||||
.. note::
|
||||
|
||||
This is actually completed for each cell in the mesh at the same time, and the full matrices are returned.
|
||||
|
||||
If ``returnP=True`` is requested in any of these methods the projection matrices are returned as a list ordered by nodes around which the fluxes were approximated::
|
||||
|
||||
# In 3D
|
||||
P = [P000, P100, P010, P110, P001, P101, P011, P111]
|
||||
# In 2D
|
||||
P = [P00, P10, P01, P11]
|
||||
# In 1D
|
||||
P = [P0, P1]
|
||||
|
||||
The derivation for ``edgeInnerProducts`` is exactly the same, however, when we
|
||||
approximate the integral using the fields around each node, the projection
|
||||
matrices look a bit different because we have 12 edges in 3D instead of just 6
|
||||
faces. The interface to the code is exactly the same.
|
||||
|
||||
|
||||
Defining Tensor Properties
|
||||
--------------------------
|
||||
|
||||
**For 3D:**
|
||||
|
||||
Depending on the number of columns (either 1, 3, or 6) of mu, the material
|
||||
property is interpreted as follows:
|
||||
|
||||
.. math::
|
||||
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & 0 & 0 \\ 0 & \mu_{1} & 0 \\ 0 & 0 & \mu_{1} \end{matrix}\right]
|
||||
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & 0 & 0 \\ 0 & \mu_{2} & 0 \\ 0 & 0 & \mu_{3} \end{matrix}\right]
|
||||
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & \mu_{4} & \mu_{5} \\ \mu_{4} & \mu_{2} & \mu_{6} \\ \mu_{5} & \mu_{6} & \mu_{3} \end{matrix}\right]
|
||||
|
||||
**For 2D:**
|
||||
|
||||
Depending on the number of columns (either 1, 2, or 3) of mu, the material property is interpreted as follows:
|
||||
|
||||
.. math::
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & 0 \\ 0 & \mu_{1} \end{matrix}\right]
|
||||
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & 0 \\ 0 & \mu_{2} \end{matrix}\right]
|
||||
|
||||
\vec{\mu} = \left[\begin{matrix} \mu_{1} & \mu_{3} \\ \mu_{3} & \mu_{2} \end{matrix}\right]
|
||||
|
||||
|
||||
Structure of Matrices
|
||||
---------------------
|
||||
|
||||
Both the isotropic, and anisotropic material properties result in a diagonal mass matrix.
|
||||
Which is nice and easy to invert if necessary, however, in the fully anisotropic case which is not aligned with the grid, the matrix is not diagonal. This can be seen for a 3D mesh in the figure below.
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import *
|
||||
mesh = Mesh.TensorMesh([10,50,3])
|
||||
m1 = np.random.rand(mesh.nC)
|
||||
m2 = np.random.rand(mesh.nC,3)
|
||||
m3 = np.random.rand(mesh.nC,6)
|
||||
M = range(3)
|
||||
M[0] = mesh.getFaceInnerProduct(m1)
|
||||
M[1] = mesh.getFaceInnerProduct(m2)
|
||||
M[2] = mesh.getFaceInnerProduct(m3)
|
||||
plt.figure(figsize=(13,5))
|
||||
for i, lab in enumerate(['Isotropic','Anisotropic','Tensor']):
|
||||
plt.subplot(131 + i)
|
||||
plt.spy(M[i],ms=0.5,color='k')
|
||||
plt.tick_params(axis='both',which='both',labeltop='off',labelleft='off')
|
||||
plt.title(lab + ' Material Property')
|
||||
plt.show()
|
||||
|
||||
|
||||
Taking Derivatives
|
||||
------------------
|
||||
|
||||
We will take the derivative of the fully anisotropic tensor for a 3D mesh, the
|
||||
other cases are easier and will not be discussed here. Let us start with one
|
||||
part of the sum which makes up :math:`\mathbf{M}^f_\Sigma` and take the
|
||||
derivative when this is multiplied by some vector :math:`\mathbf{v}`:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{P}^\top \boldsymbol{\Sigma} \mathbf{Pv}
|
||||
|
||||
Here we will let :math:`\mathbf{Pv} = \mathbf{y}` and :math:`\mathbf{y}` will have the form:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{y} = \mathbf{Pv} =
|
||||
\left[
|
||||
\begin{matrix}
|
||||
\mathbf{y}_1\\
|
||||
\mathbf{y}_2\\
|
||||
\mathbf{y}_3\\
|
||||
\end{matrix}
|
||||
\right]
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{P}^\top\Sigma\mathbf{y} =
|
||||
\mathbf{P}^\top
|
||||
\left[\begin{matrix}
|
||||
\boldsymbol{\sigma}_{1} & \boldsymbol{\sigma}_{4} & \boldsymbol{\sigma}_{5} \\
|
||||
\boldsymbol{\sigma}_{4} & \boldsymbol{\sigma}_{2} & \boldsymbol{\sigma}_{6} \\
|
||||
\boldsymbol{\sigma}_{5} & \boldsymbol{\sigma}_{6} & \boldsymbol{\sigma}_{3}
|
||||
\end{matrix}\right]
|
||||
\left[
|
||||
\begin{matrix}
|
||||
\mathbf{y}_1\\
|
||||
\mathbf{y}_2\\
|
||||
\mathbf{y}_3\\
|
||||
\end{matrix}
|
||||
\right]
|
||||
=
|
||||
\mathbf{P}^\top
|
||||
\left[
|
||||
\begin{matrix}
|
||||
\boldsymbol{\sigma}_{1}\circ \mathbf{y}_1 + \boldsymbol{\sigma}_{4}\circ \mathbf{y}_2 + \boldsymbol{\sigma}_{5}\circ \mathbf{y}_3\\
|
||||
\boldsymbol{\sigma}_{4}\circ \mathbf{y}_1 + \boldsymbol{\sigma}_{2}\circ \mathbf{y}_2 + \boldsymbol{\sigma}_{6}\circ \mathbf{y}_3\\
|
||||
\boldsymbol{\sigma}_{5}\circ \mathbf{y}_1 + \boldsymbol{\sigma}_{6}\circ \mathbf{y}_2 + \boldsymbol{\sigma}_{3}\circ \mathbf{y}_3\\
|
||||
\end{matrix}
|
||||
\right]
|
||||
|
||||
Now it is easy to take the derivative with respect to any one of the
|
||||
parameters, for example,
|
||||
:math:`\frac{\partial}{\partial\boldsymbol{\sigma}_1}`
|
||||
|
||||
.. math::
|
||||
\frac{\partial}{\partial \boldsymbol{\sigma}_1}\left(\mathbf{P}^\top\Sigma\mathbf{y}\right)
|
||||
=
|
||||
\mathbf{P}^\top
|
||||
\left[
|
||||
\begin{matrix}
|
||||
\text{diag}(\mathbf{y}_1)\\
|
||||
0\\
|
||||
0\\
|
||||
\end{matrix}
|
||||
\right]
|
||||
|
||||
Whereas :math:`\frac{\partial}{\partial\boldsymbol{\sigma}_4}`, for
|
||||
example, is:
|
||||
|
||||
.. math::
|
||||
\frac{\partial}{\partial \boldsymbol{\sigma}_4}\left(\mathbf{P}^\top\Sigma\mathbf{y}\right)
|
||||
=
|
||||
\mathbf{P}^\top
|
||||
\left[
|
||||
\begin{matrix}
|
||||
\text{diag}(\mathbf{y}_2)\\
|
||||
\text{diag}(\mathbf{y}_1)\\
|
||||
0\\
|
||||
\end{matrix}
|
||||
\right]
|
||||
|
||||
These are computed for each of the 8 projections, horizontally concatenated,
|
||||
and returned.
|
||||
|
||||
The API
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.InnerProducts.InnerProducts
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
|
||||
InvProblem
|
||||
**********
|
||||
|
||||
.. autoclass:: SimPEG.InvProblem.BaseInvProblem
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Inversion
|
||||
*********
|
||||
|
||||
.. autoclass:: SimPEG.Inversion.BaseInversion
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Directives
|
||||
**********
|
||||
|
||||
.. automodule:: SimPEG.Directives
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Inversion Components
|
||||
********************
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
api_DataMisfit
|
||||
api_Regularization
|
||||
api_Optimization
|
||||
api_Inversion
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
.. _api_Maps:
|
||||
|
||||
|
||||
SimPEG Maps
|
||||
***********
|
||||
|
||||
That's not a map...?!
|
||||
=====================
|
||||
|
||||
A SimPEG Map operates on a vector and transforms it to another space.
|
||||
We will use an example commonly applied in electromagnetics (EM) of the
|
||||
log-conductivity model.
|
||||
|
||||
.. math::
|
||||
|
||||
m = \log(\sigma)
|
||||
|
||||
Here we require a *mapping* to get from \\\(m\\\) to \\\(\\sigma\\\),
|
||||
we will call this map \\\(\\mathcal{M}\\\).
|
||||
|
||||
.. math::
|
||||
|
||||
\sigma = \mathcal{M}(m) = \exp(m)
|
||||
|
||||
In SimPEG, we use a (:class:`SimPEG.Maps.ExpMap`) to describe how to map
|
||||
back to conductivity. This is a relatively trivial example (we are just taking
|
||||
the exponential!) but by defining maps we can start to combine and manipulate
|
||||
exactly what we think about as our model, \\\(m\\\). In code, this looks like
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
M = Mesh.TensorMesh([100]) # Create a mesh
|
||||
expMap = Maps.ExpMap(M) # Create a mapping
|
||||
m = np.zeros(M.nC) # Create a model vector
|
||||
m[M.vectorCCx>0.5] = 1.0 # Set half of it to 1.0
|
||||
sig = expMap * m # Apply the mapping using *
|
||||
print m
|
||||
# [ 0. 0. 0. 1. 1. 1. ]
|
||||
print sig
|
||||
# [ 1. 1. 1. 2.718 2.718 2.718]
|
||||
|
||||
Combining Maps
|
||||
==============
|
||||
|
||||
We will use an example where we want a 1D layered earth as
|
||||
our model, but we want to map this to a 2D discretization to do our forward
|
||||
modeling. We will also assume that we are working in log conductivity still,
|
||||
so after the transformation we want to map to conductivity space.
|
||||
To do this we will introduce the vertical 1D map (:class:`SimPEG.Maps.SurjectVertical1D`),
|
||||
which does the first part of what we just described. The second part will be
|
||||
done by the :class:`SimPEG.Maps.ExpMap` described above.
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
M = Mesh.TensorMesh([7,5])
|
||||
v1dMap = Maps.SurjectVertical1D(M)
|
||||
expMap = Maps.ExpMap(M)
|
||||
myMap = expMap * v1dMap
|
||||
m = np.r_[0.2,1,0.1,2,2.9] # only 5 model parameters!
|
||||
sig = myMap * m
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import *
|
||||
import matplotlib.pyplot as plt
|
||||
M = Mesh.TensorMesh([7,5])
|
||||
v1dMap = Maps.SurjectVertical1D(M)
|
||||
expMap = Maps.ExpMap(M)
|
||||
myMap = expMap * v1dMap
|
||||
m = np.r_[0.2,1,0.1,2,2.9] # only 5 model parameters!
|
||||
sig = myMap * m
|
||||
figs, axs = plt.subplots(1,2)
|
||||
axs[0].plot(m, M.vectorCCy, 'b-o')
|
||||
axs[0].set_title('Model')
|
||||
axs[0].set_ylabel('Depth, y')
|
||||
axs[0].set_xlabel('Value, $m_i$')
|
||||
axs[0].set_xlim(0,3)
|
||||
axs[0].set_ylim(0,1)
|
||||
clbar = plt.colorbar(M.plotImage(sig,ax=axs[1],grid=True,gridOpts=dict(color='grey'))[0])
|
||||
axs[1].set_title('Physical Property')
|
||||
axs[1].set_ylabel('Depth, y')
|
||||
clbar.set_label('$\sigma = \exp(\mathbf{P}m)$')
|
||||
plt.tight_layout()
|
||||
|
||||
If you noticed, it was pretty easy to combine maps. What is even cooler is
|
||||
that the derivatives also are made for you (if everything goes right).
|
||||
Just to be sure that the derivative is correct, you should always run the test
|
||||
on the mapping that you create.
|
||||
|
||||
Taking Derivatives
|
||||
==================
|
||||
|
||||
Now that we have wrapped up the mapping, we can ensure that it is easy to take
|
||||
derivatives (or at least have access to them!). In the :class:`SimPEG.Maps.ExpMap`
|
||||
there are no dependencies between model parameters, so it will be a diagonal matrix:
|
||||
|
||||
.. math::
|
||||
|
||||
\left(\frac{\partial \mathcal{M}(m)}{\partial m}\right)_{ii} = \frac{\partial \exp(m_i)}{\partial m} = \exp(m_i)
|
||||
|
||||
Or equivalently:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \mathcal{M}(m)}{\partial m} = \text{diag}( \exp(m) )
|
||||
|
||||
The mapping API makes this really easy to test that you have got the derivative correct.
|
||||
When these are used in the inverse problem, this is extremely important!!
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import *
|
||||
import matplotlib.pyplot as plt
|
||||
M = Mesh.TensorMesh([100])
|
||||
expMap = Maps.ExpMap(M)
|
||||
m = np.zeros(M.nC)
|
||||
m[M.vectorCCx>0.5] = 1.0
|
||||
expMap.test(m, plotIt=True)
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
The :code:`IdentityMap` is the base class for all mappings, and it does absolutely nothing.
|
||||
|
||||
.. autoclass:: SimPEG.Maps.IdentityMap
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Common Maps
|
||||
===========
|
||||
|
||||
Exponential Map
|
||||
---------------
|
||||
|
||||
Electrical conductivity varies over many orders of magnitude, so it is a common
|
||||
technique when solving the inverse problem to parameterize and optimize in terms
|
||||
of log conductivity. This makes sense not only because it ensures all conductivities
|
||||
will be positive, but because this is fundamentally the space where conductivity
|
||||
lives (i.e. it varies logarithmically).
|
||||
|
||||
.. autoclass:: SimPEG.Maps.ExpMap
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Vertical 1D Map
|
||||
---------------
|
||||
|
||||
.. autoclass:: SimPEG.Maps.SurjectVertical1D
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Map 2D Cross-Section to 3D Model
|
||||
--------------------------------
|
||||
|
||||
.. autoclass:: SimPEG.Maps.Map2Dto3D
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Mesh to Mesh Map
|
||||
----------------
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import *
|
||||
import matplotlib.pyplot as plt
|
||||
M = Mesh.TensorMesh([100,100])
|
||||
h1 = Utils.meshTensor([(6,7,-1.5),(6,10),(6,7,1.5)])
|
||||
h1 = h1/h1.sum()
|
||||
M2 = Mesh.TensorMesh([h1,h1])
|
||||
V = Utils.ModelBuilder.randomModel(M.vnC, seed=79, its=50)
|
||||
v = Utils.mkvc(V)
|
||||
modh = Maps.Mesh2Mesh([M,M2])
|
||||
modH = Maps.Mesh2Mesh([M2,M])
|
||||
H = modH * v
|
||||
h = modh * H
|
||||
ax = plt.subplot(131)
|
||||
M.plotImage(v, ax=ax)
|
||||
ax.set_title('Fine Mesh (Original)')
|
||||
ax = plt.subplot(132)
|
||||
M2.plotImage(H,clim=[0,1],ax=ax)
|
||||
ax.set_title('Course Mesh')
|
||||
ax = plt.subplot(133)
|
||||
M.plotImage(h,clim=[0,1],ax=ax)
|
||||
ax.set_title('Fine Mesh (Interpolated)')
|
||||
plt.show()
|
||||
|
||||
|
||||
.. autoclass:: SimPEG.Maps.Mesh2Mesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Under the Hood
|
||||
==============
|
||||
|
||||
Combo Map
|
||||
---------
|
||||
|
||||
The ComboMap holds the information for multiplying and combining
|
||||
maps. It also uses the chain rule to create the derivative.
|
||||
Remember, any time that you make your own combination of mappings
|
||||
be sure to test that the derivative is correct.
|
||||
|
||||
.. autoclass:: SimPEG.Maps.ComboMap
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
.. _api_Mesh:
|
||||
|
||||
SimPEG Meshes
|
||||
*************
|
||||
|
||||
The Mesh objects in SimPEG provide a numerical grid on which to solve
|
||||
differential equations. Each mesh type has a similar API to make switching
|
||||
between different meshes relatively simple.
|
||||
|
||||
Overview of Meshes Available
|
||||
============================
|
||||
|
||||
The following meshes are available for use:
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_MeshCode
|
||||
|
||||
Each mesh code follows the guiding principles that are present in this
|
||||
tutorial, but the details, advantages and disadvantages differ between
|
||||
the implementations.
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Basic_Types.run()
|
||||
|
||||
|
||||
Variable Locations and Terminology
|
||||
==================================
|
||||
|
||||
We will go over the basics of using a TensorMesh, but these skills are transferable
|
||||
to the other meshes available in SimPEG. All of the mesh generation code is located
|
||||
in the Mesh package in SimPEG (i.e. SimPEG.Mesh).
|
||||
|
||||
|
||||
To create a TensorMesh we need to create mesh tensors, the widths of
|
||||
each cell of the mesh in each dimension. We will call these tensors h,
|
||||
and these will be define the constant widths of cells in each dimension
|
||||
of the TensorMesh.
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, np
|
||||
import matplotlib.pyplot as plt
|
||||
hx = np.r_[3,2,1,1,1,1,2,3]
|
||||
hy = np.r_[3,1,1,3]
|
||||
M = Mesh.TensorMesh([hx, hy])
|
||||
M.plotGrid(centers=True)
|
||||
plt.show()
|
||||
|
||||
|
||||
In this simple mesh, the hx vector defines the widths of the cell
|
||||
in the x dimension, and starts counting from the origin (0,0). The
|
||||
resulting mesh is divided into cells, and the cell-centers are
|
||||
plotted above as red circles. Other terminology for this mesh are:
|
||||
|
||||
- cell-centers
|
||||
- nodes
|
||||
- faces
|
||||
- edges
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, np
|
||||
import matplotlib.pyplot as plt
|
||||
hx = np.r_[3,2,1,1,1,1,2,3]
|
||||
hy = np.r_[3,1,1,3]
|
||||
M = Mesh.TensorMesh([hx, hy])
|
||||
M.plotGrid(faces=True, nodes=True)
|
||||
plt.title('Cell faces in the x- and y-directions.')
|
||||
plt.legend(('Nodes', 'X-Faces', 'Y-Faces'))
|
||||
plt.show()
|
||||
|
||||
Generally, the faces are used to discretize fluxes, quantities that
|
||||
leave or enter the cells. As such, these fluxes have a direction to
|
||||
them, which is normal to the cell (i.e. directly out of the cell face).
|
||||
The plot above shows that x-faces point in the x-direction, and
|
||||
y-faces point in the y-direction. The nodes are shown in blue,
|
||||
and lie at the intersection of the grid lines. In a two-dimensional
|
||||
mesh, the edges actually live in the same location as the faces,
|
||||
however, they align (or are tangent to) the face. This is easier to
|
||||
see in 3D, when the edges do not live in the same location as the faces.
|
||||
In the 3D plot below, the edge variables are seen as black triangles,
|
||||
and live on the edges(!) of the cell.
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh
|
||||
Mesh.TensorMesh([1,1,1]).plotGrid(faces=True, edges=True, centers=True, showIt=True)
|
||||
|
||||
How many of each?
|
||||
-----------------
|
||||
|
||||
When making variables that live in each of these locations, it is
|
||||
important to know how many of each variable type you are dealing with.
|
||||
SimPEG makes this pretty easy:
|
||||
|
||||
::
|
||||
|
||||
In [1]: print M
|
||||
---- 2-D TensorMesh ----
|
||||
x0: 0.00
|
||||
y0: 0.00
|
||||
nCx: 8
|
||||
nCy: 4
|
||||
hx: 3.00, 2.00, 4*1.00, 2.00, 3.00
|
||||
hy: 3.00, 2*1.00, 3.00
|
||||
|
||||
In [2]: count = {'numCells': M.nC,
|
||||
....: 'numCells_xDir': M.nCx,
|
||||
....: 'numCells_yDir': M.nCy,
|
||||
....: 'numCells_vector': M.vnC}
|
||||
|
||||
In [3]: print 'This mesh has %(numCells)d cells, which is %(numCells_xDir)d*%(numCells_yDir)d!!' % count
|
||||
|
||||
This mesh has 32 cells, which is 8*4!!
|
||||
|
||||
In [4]: print count
|
||||
|
||||
{
|
||||
'numCells_vector': array([8, 4]),
|
||||
'numCells_yDir': 4,
|
||||
'numCells_xDir': 8,
|
||||
'numCells': 32
|
||||
}
|
||||
|
||||
SimPEG also counts the nodes, faces, and edges.
|
||||
|
||||
::
|
||||
|
||||
Nodes: M.nN, M.nNx, M.nNy, M.nNz, M.vnN
|
||||
Faces: M.nF, M.nFx, M.nFy, M.nFz, M.vnF, M.vnFx, M.vnFy, M.vnFz
|
||||
Edges: M.nE, M.nEx, M.nEy, M.nEz, M.vnE, M.vnEx, M.vnEy, M.vnEz
|
||||
|
||||
Face and edge variables have different counts depending on
|
||||
the dimension of the direction that you are interested in.
|
||||
In a 4x5 mesh, for example, there is a 5x5 grid of x-faces,
|
||||
and a 4x6 grid of y-faces. You can count them below!
|
||||
As such, the vnF(x,y,z) and vnE(x,y,z) properties give the
|
||||
vector grid size.
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh
|
||||
Mesh.TensorMesh([4,5]).plotGrid(faces=True, showIt=True)
|
||||
|
||||
|
||||
Making Tensors
|
||||
--------------
|
||||
|
||||
For tensor meshes, there are some additional functions that can come
|
||||
in handy. For example, creating mesh tensors can be a bit time
|
||||
consuming, these can be created speedily by just giving numbers
|
||||
and sizes of padding. See the example below, that follows this
|
||||
notation::
|
||||
|
||||
h1 = (
|
||||
(cellSize, numPad, [, increaseFactor]),
|
||||
(cellSize, numCore),
|
||||
(cellSize, numPad, [, increaseFactor])
|
||||
)
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
h1 = [(10, 5, -1.3), (5, 20), (10, 3, 1.3)]
|
||||
M = Mesh.TensorMesh([h1, h1], x0='CN')
|
||||
M.plotGrid(showIt=True)
|
||||
|
||||
.. note::
|
||||
|
||||
You can center your mesh by passing a 'C' for the x0[i] position.
|
||||
A 'N' will make the entire mesh negative, and a '0' (or a 0) will
|
||||
make the mesh start at zero.
|
||||
|
||||
Hopefully, you now know how to create TensorMesh objects in SimPEG,
|
||||
and by extension you are also familiar with how to create and use
|
||||
other types of meshes in this SimPEG framework.
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.BaseMesh.BaseMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,68 @@
|
||||
.. _api_MeshCode:
|
||||
|
||||
Tensor Mesh
|
||||
===========
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.TensorMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Cylindrical Mesh
|
||||
================
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.CylMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Tree Mesh
|
||||
=========
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.TreeMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Curvilinear Mesh
|
||||
================
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.CurvilinearMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Base Rectangular Mesh
|
||||
=====================
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.BaseMesh.BaseRectangularMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
Base Tensor Mesh
|
||||
================
|
||||
|
||||
.. autoclass:: SimPEG.Mesh.TensorMesh.BaseTensorMesh
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Mesh IO
|
||||
=======
|
||||
|
||||
.. automodule:: SimPEG.Mesh.MeshIO
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
|
||||
|
||||
Mesh Viewing
|
||||
============
|
||||
|
||||
.. automodule:: SimPEG.Mesh.View
|
||||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
Optimize
|
||||
********
|
||||
|
||||
.. automodule:: SimPEG.Optimization
|
||||
:show-inheritance:
|
||||
:private-members:
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,29 @@
|
||||
SimPEG PropMaps
|
||||
***************
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
Property
|
||||
--------
|
||||
|
||||
.. autoclass:: SimPEG.PropMaps.Property
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
PropMap
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.PropMaps.PropMap
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
PropModel
|
||||
---------
|
||||
|
||||
.. autoclass:: SimPEG.PropMaps.PropModel
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
|
||||
Regularization
|
||||
**************
|
||||
|
||||
If there is one model that has a misfit that equals the desired tolerance, then there are infinitely many other models which can fit to the same degree. The challenge is to find that model which has the desired characteristics and is compatible with a priori information. A single model can be selected from an infinite ensemble by measuring the length, or norm, of each model. Then a smallest, or sometimes largest, member can be isolated. Our goal is to design a norm that embodies our prior knowledge and, when minimized, yields a realistic candidate for the solution of our problem. The norm can penalize variation from a reference model, spatial derivatives of the model, or some combination of these.
|
||||
|
||||
Tikhonov Regularization
|
||||
=======================
|
||||
|
||||
Here we will define regularization of a model, m, in general however, this should be thought of as (m-m_ref) but otherwise it is exactly the same:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) = \int_\Omega \frac{\alpha_x}{2}\left(\frac{\partial m}{\partial x}\right)^2 + \frac{\alpha_y}{2}\left(\frac{\partial m}{\partial y}\right)^2 \partial v
|
||||
|
||||
Our discrete gradient operator works on cell centers and gives the derivative on the cell faces, which is not where we want to be evaluating this integral. We need to average the values back to the cell-centers before we integrate. To avoid null spaces, we square first and then average. In 2D with ij notation it looks like this:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) \approx \sum_{ij} \left[\frac{\alpha_x}{2}\left[\left(\frac{m_{i+1,j} - m_{i,j}}{h}\right)^2 + \left(\frac{m_{i,j} - m_{i-1,j}}{h}\right)^2\right] \\
|
||||
+ \frac{\alpha_y}{2}\left[\left(\frac{m_{i,j+1} - m_{i,j}}{h}\right)^2 + \left(\frac{m_{i,j} - m_{i,j-1}}{h}\right)^2\right]
|
||||
\right]h^2
|
||||
|
||||
If we let D_1 be the derivative matrix in the x direction
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{D}_1 = \mathbf{I}_2\otimes\mathbf{d}_1
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{D}_2 = \mathbf{d}_2\otimes\mathbf{I}_1
|
||||
|
||||
Where d_1 is the one dimensional derivative:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{d}_1 = \frac{1}{h} \left[ \begin{array}{cccc}
|
||||
-1 & 1 & & \\
|
||||
& \ddots & \ddots&\\
|
||||
& & -1 & 1\end{array} \right]
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) \approx \mathbf{v}^\top \left[\frac{\alpha_x}{2}\mathbf{A}_1 (\mathbf{D}_1 m) \odot (\mathbf{D}_1 m) + \frac{\alpha_y}{2}\mathbf{A}_2 (\mathbf{D}_2 m) \odot (\mathbf{D}_2 m) \right]
|
||||
|
||||
Recall that this is really a just point wise multiplication, or a diagonal matrix times a vector. When we multiply by something in a diagonal we can interchange and it gives the same results (i.e. it is point wise)
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{a\odot b} = \text{diag}(\mathbf{a})\mathbf{b} = \text{diag}(\mathbf{b})\mathbf{a} = \mathbf{b\odot a}
|
||||
|
||||
and the transpose also is true (but the sizes have to make sense...):
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{a}^\top\text{diag}(\mathbf{b}) = \mathbf{b}^\top\text{diag}(\mathbf{a})
|
||||
|
||||
So R(m) can simplify to:
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) \approx \mathbf{m}^\top \left[\frac{\alpha_x}{2}\mathbf{D}_1^\top \text{diag}(\mathbf{A}_1^\top\mathbf{v}) \mathbf{D}_1 + \frac{\alpha_y}{2}\mathbf{D}_2^\top \text{diag}(\mathbf{A}_2^\top \mathbf{v}) \mathbf{D}_2 \right] \mathbf{m}
|
||||
|
||||
We will define W_x as:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{W}_x = \sqrt{\alpha_x}\text{diag}\left(\sqrt{\mathbf{A}_1^\top\mathbf{v}}\right) \mathbf{D}_1
|
||||
|
||||
|
||||
And then W as a tall matrix of all of the different regularization terms:
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{W} = \left[ \begin{array}{c}
|
||||
\mathbf{W}_s\\
|
||||
\mathbf{W}_x\\
|
||||
\mathbf{W}_y\end{array} \right]
|
||||
|
||||
Then we can write
|
||||
|
||||
.. math::
|
||||
|
||||
R(m) \approx \frac{1}{2}\mathbf{m^\top W^\top W m}
|
||||
|
||||
The API
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.Regularization.BaseRegularization
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
.. autoclass:: SimPEG.Regularization.Tikhonov
|
||||
:show-inheritance:
|
||||
:members:
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
.. _api_Solver:
|
||||
|
||||
|
||||
Solver
|
||||
******
|
||||
|
||||
BYOS
|
||||
====
|
||||
|
||||
The numerical linear algebra solver that you use will ultimately be the
|
||||
bottleneck of your large scale inversion. To be the most flexible, SimPEG
|
||||
provides wrappers rather than a comprehensive set of solvers (i.e. BYOS).
|
||||
|
||||
The interface is as follows::
|
||||
|
||||
A # Where A is a sparse matrix (or linear operator)
|
||||
Ainv = Solver(A, **solverOpts) # Create a solver object with key word arguments
|
||||
x = Ainv * b # Where b is a numpy array of shape (n,) or (n,*)
|
||||
Ainv.clean() # This cleans the memory footprint (if any)
|
||||
|
||||
.. note::
|
||||
|
||||
This is somewhat an abuse of notation for solvers as we never actually
|
||||
create A inverse. Instead we are creating an object that acts like A
|
||||
inverse, whether that be a Krylov subspace solver or an LU decomposition.
|
||||
|
||||
To wrap up solvers in scipy.sparse.linalg it takes one line of code::
|
||||
|
||||
|
||||
Solver = SolverWrapD(sp.linalg.spsolve, factorize=False)
|
||||
SolverLU = SolverWrapD(sp.linalg.splu, factorize=True)
|
||||
SolverCG = SolverWrapI(sp.linalg.cg)
|
||||
|
||||
.. note::
|
||||
|
||||
The above solvers are loaded into the base name space of SimPEG.
|
||||
|
||||
.. seealso::
|
||||
|
||||
- https://bitbucket.org/petsc/petsc4py
|
||||
- https://github.com/bfroehle/pymumps
|
||||
- https://github.com/rowanc1/pymatsolver
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
.. autofunction:: SimPEG.Utils.SolverUtils.SolverWrapD
|
||||
:noindex:
|
||||
|
||||
.. autofunction:: SimPEG.Utils.SolverUtils.SolverWrapI
|
||||
:noindex:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
.. _api_Tests:
|
||||
|
||||
Testing SimPEG
|
||||
==============
|
||||
|
||||
.. automodule:: SimPEG.Tests
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,11 @@
|
||||
Utilities
|
||||
*********
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_Solver
|
||||
api_Maps
|
||||
api_PropMaps
|
||||
api_Utils
|
||||
api_Tests
|
||||
@@ -0,0 +1,92 @@
|
||||
Utils
|
||||
*****
|
||||
|
||||
.. automodule:: SimPEG.Utils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Matrix Utilities
|
||||
================
|
||||
|
||||
.. automodule:: SimPEG.Utils.matutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Solver Utilities
|
||||
================
|
||||
|
||||
.. automodule:: SimPEG.Utils.SolverUtils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Curv Utilities
|
||||
==============
|
||||
|
||||
.. automodule:: SimPEG.Utils.curvutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Mesh Utilities
|
||||
==============
|
||||
|
||||
.. automodule:: SimPEG.Utils.meshutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Model Builder Utilities
|
||||
=======================
|
||||
|
||||
.. automodule:: SimPEG.Utils.ModelBuilder
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Interpolation Utilities
|
||||
=======================
|
||||
|
||||
.. automodule:: SimPEG.Utils.interputils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Counter Utilities
|
||||
=================
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
class MyClass(object):
|
||||
def __init__(self, url):
|
||||
self.counter = Counter()
|
||||
|
||||
@count
|
||||
def MyMethod(self):
|
||||
pass
|
||||
|
||||
@timeIt
|
||||
def MySecondMethod(self):
|
||||
pass
|
||||
|
||||
c = MyClass('blah')
|
||||
for i in range(100): c.MyMethod()
|
||||
for i in range(300): c.MySecondMethod()
|
||||
c.counter.summary()
|
||||
|
||||
|
||||
.. code-block:: text
|
||||
:linenos:
|
||||
|
||||
Counters:
|
||||
MyClass.MyMethod : 100
|
||||
|
||||
Times: mean sum
|
||||
MyClass.MySecondMethod : 1.70e-06, 5.10e-04, 300x
|
||||
|
||||
|
||||
|
||||
The API
|
||||
-------
|
||||
|
||||
.. automodule:: SimPEG.Utils.CounterUtils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
Why SimPEG?
|
||||
===========
|
||||
|
||||
Our essential functions as researchers are the pursuit and dissemination of knowledge through research and education. As scientists we
|
||||
seek to find models that reproduce the observations that we make in the world. In geophysics, we use inverse theory to mathematically
|
||||
create models of the earth from measured data. It is a difficult problem with many moving pieces: physics, discretization, simulation,
|
||||
regularization, optimization, computer science, linear algebra, geology. Exploring each of these disciplines can take a career, if you
|
||||
are so inclined, but as geophysicists we care about the combination: how to pull these disciplines together to answer our questions.
|
||||
This is the first problem we hope to help solve: to create a toolbox for the geophysicist that allows you to work at a high level and
|
||||
keep your geophysical question in focus. However, a toolbox is not enough. The research questions that we are interested in surround
|
||||
the integration of information to make better decisions.
|
||||
|
||||
We believe that the feedback loops in the geosciences could use some serious work. For example, collect multiple data-sets from the
|
||||
same field area (geology, seismic, electromagnetics, hydrogeology), process the data separately, and then reconvene with your
|
||||
multidisciplinary team. You may be rather surprised (or not) that the everyone has a (completely!?) different model. Dissonant at best,
|
||||
but often conflicting in the details. Therein lies the second problem: how do we integrate these geoscience fields? Not by force or
|
||||
even by default, but at least to have the option of quantitative communication and built in feedback loops. What we require is an
|
||||
implementation that is inherently and unequivocally modular, with all pieces available to manipulation. Black-box software, where the
|
||||
implementations are hidden, obfuscated, or difficult to manipulate, do not promote experimentation and investigation. We are working on
|
||||
a framework that exposes the details of the implementation to the geophysicist in a manner that promotes productivity and question
|
||||
based interrogation. This framework can be easily extended to encompass many geophysical problems and is built with the inverse problem
|
||||
as the fundamental goal.
|
||||
|
||||
The future we see is a mix of tools that span our disciplines, and a framework that allows us to integrate many different types of
|
||||
geophysical data so that we can communicate effectively and experiment efficiently. A toolbox combined with a framework that allows you
|
||||
to solve your own problems, and creates opportunities for us to work together to better image and understand the subsurface. What we
|
||||
are building is called SimPEG, simulation and parameter estimation in geophysics. We are building it in the open. We are testing it.
|
||||
Breaking it. Building it. Fixing it. Using it. If you believe, like we do, that geophysics can be more innovative and informative in
|
||||
the open and that these tools are necessary and invaluable in education as well as research, then you should get in touch. There is a
|
||||
lot of work to do!
|
||||
|
||||
The Big Picture
|
||||
---------------
|
||||
|
||||
Defining a well-posed inverse problem and solving it is a complex task that requires many components that must interact. It is helpful
|
||||
to view this task as a workflow in which various elements are explicitly identified and integrated. The figure below outlines the inversion components that consists of inputs, implementation, and evaluation. The inputs are composed of the geophysical data, the equations which are a mathematical description of the governing physics, and prior knowledge or assumptions about the setting. The implementation consists of two broad categories: the forward simulation and the inversion. The **forward simulation** is the means by which we solve the governing equations given a model and the **inversion components** evaluate and update this model. We are considering a gradient based approach, which updates the model through an optimization routine. The output of this implementation is a model, which, prior to interpretation, must be evaluated. This requires considering, and often re-assessing, the choices and assumptions made in both the input and implementation stages.
|
||||
|
||||
.. image:: ../../images/InversionWorkflow-PreSimPEG.png
|
||||
:width: 400 px
|
||||
:alt: Components
|
||||
:align: center
|
||||
|
||||
|
||||
A Comprehensive Framework
|
||||
-------------------------
|
||||
|
||||
There are an overwhelming amount of choices to be made as one works through the forward modeling and inversion process (see figure above). As a result, software implementations of this workflow often become complex and highly interdependent, making it difficult to interact with and to ask other scientists to pick up and change. Our approach to handling this complexity is to propose a framework, (see below), that compartmentalizes the implementation of inversions into various units. We present it in this specific modular style, as each unit contains a targeted subset of choices crucial to the inversion process.
|
||||
|
||||
.. image:: ../../images/InversionWorkflow.png
|
||||
:width: 400 px
|
||||
:alt: Framework
|
||||
:align: center
|
||||
|
||||
The process of obtaining an acceptable model from an inversion generally requires the geophysicist to perform several iterations of the inversion workflow, rethinking and redesigning each piece of the framework to ensure it is appropriate in the current context. Inversions are experimental and empirical by nature and our software package is designed to facilitate this iterative process. To accomplish this, we have divided the inversion methodology into eight major components (See figure above). The :class:`SimPEG.Mesh.BaseMesh.BaseMesh` class handles the discretization of the earth and also provides numerical operators. The forward simulation is split into two classes, the :class:`SimPEG.Survey.BaseSurvey` and the :class:`SimPEG.Problem.BaseProblem`. The :class:`SimPEG.Survey.BaseSurvey` class handles the geometry of a geophysical problem as well as sources. The :class:`SimPEG.Problem.BaseProblem` class handles the simulation of the physics for the geophysical problem of interest. Although created independently, these two classes must be paired to form all of the components necessary for a geophysical forward simulation and calculation of the sensitivity. The :class:`SimPEG.Problem.BaseProblem` creates geophysical fields given a source from the :class:`SimPEG.Survey.BaseSurvey`. The :class:`SimPEG.Survey.BaseSurvey` interpolates these fields to the receiver locations and converts them to the appropriate data type, for example, by selecting only the measured components of the field. Each of these operations may have associated derivatives with respect to the model and the computed field; these are included in the calculation of the sensitivity. For the inversion, a :class:`SimPEG.DataMisfit.BaseDataMisfit` is chosen to capture the goodness of fit of the predicted data and a :class:`SimPEG.Regularization.BaseRegularization` is chosen to handle the non-uniqueness. These inversion elements and an Optimization routine are combined into an inverse problem class :class:`SimPEG.InvProblem.BaseInvProblem`. :class:`SimPEG.InvProblem.BaseInvProblem` is the mathematical statement that will be numerically solved by running an Inversion. The :class:`SimPEG.Inversion.BaseInversion` class handles organization and dispatch of directives between all of the various pieces of the framework.
|
||||
|
||||
The arrows in the figure above indicate what each class takes as a primary argument. For example, both the :class:`SimPEG.Problem.BaseProblem` and :class:`SimPEG.Regularization.BaseRegularization` classes take a :class:`SimPEG.Mesh.BaseMesh.BaseMesh` class as an argument. The diagram does not show class inheritance, as each of the base classes outlined have many subtypes that can be interchanged. The :class:`SimPEG.Mesh.BaseMesh.BaseMesh` class, for example, could be a regular Cartesian mesh :class:`SimPEG.Mesh.TensorMesh` or a cylindrical coordinate mesh :class:`SimPEG.Mesh.CylMesh`, which have many properties in common. These common features, such as both meshes being created from tensor products, can be exploited through inheritance of base classes, and differences can be expressed through subtype polymorphism. Please look at the documentation here for more in-depth information.
|
||||
|
||||
|
||||
.. include:: ../../../CITATION.rst
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
.. include:: ../../../AUTHORS.rst
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
.. include:: ../../../LICENSE
|
||||
@@ -0,0 +1,80 @@
|
||||
.. _api_installing:
|
||||
|
||||
Getting Started with SimPEG
|
||||
***************************
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
- Python 2.7
|
||||
- NumPy 1.8 (or greater)
|
||||
- SciPy 0.13 (or greater)
|
||||
- matplotlib 1.3 (or greater)
|
||||
- Cython 0.20 (or greater)
|
||||
|
||||
Installing Python
|
||||
=================
|
||||
|
||||
Python is available on all major operating systems, but if you are getting started with python
|
||||
it is best to use a package manager such as
|
||||
`Continuum Anaconda <https://store.continuum.io/cshop/anaconda/>`_ or
|
||||
`Enthought Canopy <https://www.enthought.com/products/canopy/>`_.
|
||||
You can download the package manager and use it to install the dependencies above.
|
||||
|
||||
|
||||
Installing SimPEG
|
||||
=================
|
||||
|
||||
SimPEG is on pip!!::
|
||||
|
||||
pip install SimPEG
|
||||
|
||||
|
||||
Installing from Source
|
||||
----------------------
|
||||
|
||||
First (you need git)::
|
||||
|
||||
git clone https://github.com/simpeg/simpeg
|
||||
|
||||
Second (from the root of the simpeg repository)::
|
||||
|
||||
python setup.py install
|
||||
|
||||
|
||||
Useful Links
|
||||
============
|
||||
An enormous amount of information (including tutorials and examples) can be found on the official websites of the packages
|
||||
|
||||
* `Python Website <http://www.python.org/>`_
|
||||
* `Numpy Website <http://www.numpy.org/>`_
|
||||
* `SciPy Website <http://www.scipy.org/>`_
|
||||
* `Matplotlib <http://matplotlib.org/>`_
|
||||
|
||||
Python for scientific computing
|
||||
-------------------------------
|
||||
|
||||
* `Python for Scientists <https://sites.google.com/site/pythonforscientists/>`_ Links to commonly used packages, Matlab to Python comparison
|
||||
* `Python Wiki <http://wiki.python.org/moin/NumericAndScientific>`_ Lists packages and resources for scientific computing in Python
|
||||
|
||||
Numpy and Matlab
|
||||
----------------
|
||||
|
||||
* `NumPy for Matlab Users <http://wiki.scipy.org/NumPy_for_Matlab_Users>`_
|
||||
* `Python vs Matlab <https://sites.google.com/site/pythonforscientists/python-vs-matlab>`_
|
||||
|
||||
Lessons in Python
|
||||
-----------------
|
||||
|
||||
* `Software Carpentry <http://software-carpentry.org/v4/python/index.html>`_
|
||||
* `Introduction to NumPy and Matplotlib <http://www.youtube.com/watch?v=3Fp1zn5ao2M>`_
|
||||
|
||||
Editing Python
|
||||
--------------
|
||||
|
||||
There are numerous ways to edit and test Python (see `PythonWiki <http://wiki.python.org/moin/PythonEditors>`_ for an overview) and in our group at least the following options are being used:
|
||||
|
||||
* `Sublime <http://www.sublimetext.com/>`_
|
||||
* `iPython Notebook <http://ipython.org/notebook.html>`_
|
||||
* `iPython <http://ipython.org/>`_
|
||||
* `Enthought Canopy <https://www.enthought.com/products/canopy/>`_
|
||||
@@ -0,0 +1,157 @@
|
||||
.. math::
|
||||
|
||||
\renewcommand{\div}{\nabla\cdot\,}
|
||||
\newcommand{\grad}{\vec \nabla}
|
||||
\newcommand{\curl}{{\vec \nabla}\times\,}
|
||||
\newcommand{\dcurl}{{\mathbf C}}
|
||||
\newcommand{\dgrad}{{\mathbf G}}
|
||||
\newcommand{\Acf}{{\mathbf A_c^f}}
|
||||
\newcommand{\Ace}{{\mathbf A_c^e}}
|
||||
\renewcommand{\S}{{\mathbf \Sigma}}
|
||||
\renewcommand{\Div}{{\mathbf {Div}}}
|
||||
\renewcommand{\Grad}{{\mathbf {Grad}}}
|
||||
\newcommand{\St}{{\mathbf \Sigma_\tau}}
|
||||
\newcommand{\diag}{\mathbf{diag}}
|
||||
\newcommand{\M}{{\mathbf M}}
|
||||
\newcommand{\Me}{{\M^e}}
|
||||
\newcommand{\Mes}[1]{{\M^e_{#1}}}
|
||||
\newcommand{\be}{\mathbf{e}}
|
||||
\newcommand{\bj}{\mathbf{j}}
|
||||
\newcommand{\bphi}{\mathbf{\phi}}
|
||||
\newcommand{\bq}{\mathbf{q}}
|
||||
\newcommand{\bJ}{\mathbf{J}}
|
||||
\newcommand{\bG}{\mathbf{G}}
|
||||
\newcommand{\bP}{\mathbf{P}}
|
||||
\newcommand{\bA}{\mathbf{A}}
|
||||
\newcommand{\bm}{\mathbf{m}}
|
||||
\newcommand{\B}{\vec{B}}
|
||||
\newcommand{\D}{\vec{D}}
|
||||
\renewcommand{\H}{\vec{H}}
|
||||
\renewcommand {\j} { {\vec j} }
|
||||
\newcommand {\h} { {\vec h} }
|
||||
\renewcommand {\b} { {\vec b} }
|
||||
\newcommand {\e} { {\vec e} }
|
||||
\newcommand {\c} { {\vec c} }
|
||||
\renewcommand {\d} { {\vec d} }
|
||||
\renewcommand {\u} { {\vec u} }
|
||||
\newcommand{\I}{\vec{I}}
|
||||
|
||||
|
||||
Direct Current Resistivity
|
||||
**************************
|
||||
|
||||
`SimPEG.DCIP` uses SimPEG as the framework for the forward and inverse
|
||||
direct current (DC) resistivity and induced polarization (IP) geophysical problems.
|
||||
|
||||
|
||||
DC resistivity survey
|
||||
=====================
|
||||
|
||||
Electrical resistivity of subsurface materials is measured by causing an electrical current to flow in the earth between one pair of electrodes while the voltage across a second pair of electrodes is measured. The result is an "apparent" resistivity which is a value representing the weighted average resistivity over a volume of the earth. Variations in this measurement are caused by variations in the soil, rock, and pore fluid electrical resistivity. Surveys require contact with the ground, so they can be labour intensive. Results are sometimes interpreted directly, but more commonly, 1D, 2D or 3D models are estimated using inversion procedures (`GPG <http://www.eos.ubc.ca/courses/eosc350/content/>`_).
|
||||
|
||||
|
||||
Background
|
||||
==========
|
||||
|
||||
As direct current (DC) implies, in DC resistivity survey, we assume steady-state. We consider Maxwell's equations in steady state as
|
||||
|
||||
.. math::
|
||||
|
||||
\curl \frac{1}{\mu} \vec{b} - \j = \j_s \\
|
||||
|
||||
\curl \e = 0
|
||||
|
||||
Then by taking \\(\\div\\) of the first equation, we have
|
||||
|
||||
.. math::
|
||||
|
||||
- \div\j = q \\
|
||||
|
||||
|
||||
where
|
||||
|
||||
.. math::
|
||||
|
||||
\div \j_s = q = I(\delta(\vec{r}-\vec{r}_{s+})-\delta(\vec{r}-\vec{r}_{s-}))
|
||||
|
||||
Since \\(\\curl \\e = 0\\), we have
|
||||
|
||||
.. math::
|
||||
|
||||
\e = \grad \phi
|
||||
|
||||
And by Ohm's law, we have
|
||||
|
||||
.. math::
|
||||
|
||||
\j = \sigma \grad \phi
|
||||
|
||||
Finally, we can compute the solution of the system:
|
||||
|
||||
.. math::
|
||||
|
||||
- \div\j = q
|
||||
|
||||
\j = \sigma \grad \phi
|
||||
|
||||
\frac{\partial \phi}{\partial r}\Big|_{\partial \Omega_{BC}} = 0
|
||||
|
||||
|
||||
Discretization
|
||||
==============
|
||||
|
||||
By using finite volume method (FVM), we discretize our system as
|
||||
|
||||
.. math::
|
||||
|
||||
-\Div \bj = \bq
|
||||
|
||||
\diag(\Acf^{T}\sigma^{-1}) \bj = \Grad \bphi
|
||||
|
||||
Here boundary condtions are embedded in the discrete differential operators. With some linear algebra we have
|
||||
|
||||
.. math::
|
||||
|
||||
\bA\bphi = -\bq
|
||||
|
||||
where
|
||||
|
||||
.. math::
|
||||
|
||||
\bA = \Div (\diag(\Acf^{T}\sigma^{-1}))^{-1} \Grad
|
||||
|
||||
By solving this linear equation, we can compute the solution of \\(\\phi\\). Based on this discretization, we derive sensitivity in discretized space. Sensitivity matrix can be in general can be written as
|
||||
|
||||
.. math ::
|
||||
|
||||
\bJ = -\bP\bA^{-1}\bG
|
||||
|
||||
where
|
||||
|
||||
.. math ::
|
||||
|
||||
\bP: \text{Projection}
|
||||
|
||||
\bJ = \bP\frac{\partial \phi}{\partial \bm}
|
||||
|
||||
Here \\(\\bm\\) indicates model parameters in discretized space.
|
||||
|
||||
Verification
|
||||
============
|
||||
|
||||
Comparing to the analytic function:
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.DC_Analytic_Dipole.run(plotIt=True)
|
||||
|
||||
|
||||
API for DC codes
|
||||
================
|
||||
|
||||
.. automodule:: SimPEG.DCIP.BaseDC
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -0,0 +1,197 @@
|
||||
.. _api_FDEM:
|
||||
|
||||
.. math::
|
||||
\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 :math:`e^{i \omega t}` convention, so we define our
|
||||
Fourier Transform pair as
|
||||
|
||||
.. math ::
|
||||
F(\omega) = \int_{-\infty}^{\infty} f(t) e^{- i \omega t} dt \\
|
||||
|
||||
f(t) = \frac{1}{2\pi}\int_{-\infty}^{\infty} F(\omega) e^{i \omega t} d \omega
|
||||
|
||||
where :math:`\omega` is angular frequency, :math:`t` is time, :math:`F(\omega)` is the function defined in the frequency domain and :math:`f(t)` is the function defined in the time domain.
|
||||
|
||||
|
||||
Maxwell's Equations
|
||||
===================
|
||||
|
||||
In the frequency domain, Maxwell's equations are given by
|
||||
|
||||
.. math ::
|
||||
\curl \vec{E} + i \omega \vec{B} = \vec{S_m}\\
|
||||
|
||||
\curl \vec{H} - \vec{J} - i \omega \vec{D} = \vec{S_e} \\
|
||||
|
||||
\div \vec{B} = 0 \\
|
||||
|
||||
\div \vec{D} = \rho_f
|
||||
|
||||
where:
|
||||
|
||||
- :math:`\vec{E}` : electric field (:math:`V/m` )
|
||||
- :math:`\vec{H}` : magnetic field (:math:`A/m` )
|
||||
- :math:`\vec{B}` : magnetic flux density (:math:`Wb/m^2` )
|
||||
- :math:`\vec{D}` : electric displacement / electric flux density (:math:`C/m^2` )
|
||||
- :math:`\vec{J}` : electric current density (:math:`A/m^2` )
|
||||
- :math:`\vec{S_m}` : magnetic source term (:math:`V/m^2` )
|
||||
- :math:`\vec{S_e}` : electric source term (:math:`A/m^2` )
|
||||
- :math:`\rho_f` : free charge density (:math:`\Omega m` )
|
||||
|
||||
|
||||
|
||||
Constitutive Relations
|
||||
----------------------
|
||||
|
||||
The fields and fluxes are related through the constitutive relations. At each frequency, they are given by
|
||||
|
||||
.. math ::
|
||||
\vec{J} = \sigma \vec{E} \\
|
||||
|
||||
\vec{B} = \mu \vec{H} \\
|
||||
|
||||
\vec{D} = \varepsilon \vec{E}
|
||||
|
||||
where:
|
||||
|
||||
- :math:`\sigma` : electrical conductivity (:math:`S/m`)
|
||||
- :math:`\mu` : magnetic permeability (:math:`H/m`)
|
||||
- :math:`\varepsilon` : dielectric permittivity (:math:`F/m`)
|
||||
|
||||
:math:`\sigma`, :math:`\mu`, :math:`\varepsilon` are physical properties which depend on the material. :math:`\sigma` describes how easily electric current passes through a material, :math:`\mu` describes how easily a material is magnetized, and :math:`\varepsilon` describes how easily a material is electrically polarized. In most geophysical applications of EM, :math:`\sigma` is the the primary physical property of interest, and :math:`\mu`, :math:`\varepsilon` are assumed to have their free-space values :math:`\mu_0 = 4\pi \times 10^{-7} H/m` , :math:`\varepsilon_0 = 8.85 \times 10^{-12} F/m`
|
||||
|
||||
|
||||
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
|
||||
|
||||
.. math ::
|
||||
\nabla \times \vec{E} + i \omega \vec{B} = \vec{S_m} \\
|
||||
\nabla \times \vec{H} - \vec{J} = \vec{S_e}
|
||||
|
||||
|
||||
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:
|
||||
|
||||
.. math ::
|
||||
\nabla \times \vec{E} + i \omega \vec{B} = \vec{S}_m \\
|
||||
\nabla \times \mu^{-1} \vec{B} - \sigma \vec{E} = \vec{S}_e
|
||||
|
||||
The H-J formulation is in terms of the current density and the magnetic field:
|
||||
|
||||
.. math ::
|
||||
\nabla \times \sigma^{-1} \vec{J} + i \omega \mu \vec{H} = \vec{S}_m \\
|
||||
\nabla \times \vec{H} - \vec{J} = \vec{S}_e
|
||||
|
||||
|
||||
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 :math:`r`, :math:`z` faces and :math:`\theta` edges)
|
||||
|
||||
.. figure:: ../../images/finitevolrealestate.png
|
||||
:align: center
|
||||
:scale: 60 %
|
||||
|
||||
For the two formulations, the discretization of the physical properties, fields and fluxes are summarized below.
|
||||
|
||||
.. figure:: ../../images/ebjhdiscretizations.png
|
||||
:align: center
|
||||
:scale: 60 %
|
||||
|
||||
Note that resistivity is the inverse of conductivity, :math:`\rho = \sigma^{-1}`.
|
||||
|
||||
|
||||
E-B Formulation
|
||||
---------------
|
||||
|
||||
.. math ::
|
||||
\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}
|
||||
|
||||
H-J Formulation
|
||||
---------------
|
||||
|
||||
.. math ::
|
||||
\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}
|
||||
|
||||
|
||||
.. Forward Problem
|
||||
.. ===============
|
||||
|
||||
.. Inverse Problem
|
||||
.. ===============
|
||||
|
||||
API
|
||||
===
|
||||
|
||||
FDEM Problem
|
||||
------------
|
||||
|
||||
.. automodule:: SimPEG.EM.FDEM.ProblemFDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
FDEM Survey
|
||||
-----------
|
||||
|
||||
.. automodule:: SimPEG.EM.FDEM.SurveyFDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. automodule:: SimPEG.EM.FDEM.SrcFDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
.. automodule:: SimPEG.EM.FDEM.RxFDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
FDEM Fields
|
||||
-----------
|
||||
|
||||
.. automodule:: SimPEG.EM.FDEM.FieldsFDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
@@ -0,0 +1,387 @@
|
||||
.. _api_TDEM:
|
||||
|
||||
|
||||
.. math::
|
||||
|
||||
\renewcommand{\div}{\nabla\cdot\,}
|
||||
\newcommand{\grad}{\vec \nabla}
|
||||
\newcommand{\curl}{{\vec \nabla}\times\,}
|
||||
\newcommand {\J}{{\vec J}}
|
||||
\renewcommand{\H}{{\vec H}}
|
||||
\newcommand {\E}{{\vec E}}
|
||||
\newcommand{\dcurl}{{\mathbf C}}
|
||||
\newcommand{\dgrad}{{\mathbf G}}
|
||||
\newcommand{\Acf}{{\mathbf A_c^f}}
|
||||
\newcommand{\Ace}{{\mathbf A_c^e}}
|
||||
\renewcommand{\S}{{\mathbf \Sigma}}
|
||||
\newcommand{\St}{{\mathbf \Sigma_\tau}}
|
||||
\newcommand{\T}{{\mathbf T}}
|
||||
\newcommand{\Tt}{{\mathbf T_\tau}}
|
||||
\newcommand{\diag}[1]{\,{\sf diag}\left( #1 \right)}
|
||||
\newcommand{\M}{{\mathbf M}}
|
||||
\newcommand{\MfMui}{{\M^f_{\mu^{-1}}}}
|
||||
\newcommand{\MeSig}{{\M^e_\sigma}}
|
||||
\newcommand{\MeSigInf}{{\M^e_{\sigma_\infty}}}
|
||||
\newcommand{\MeSigO}{{\M^e_{\sigma_0}}}
|
||||
\newcommand{\Me}{{\M^e}}
|
||||
\newcommand{\Mes}[1]{{\M^e_{#1}}}
|
||||
\newcommand{\Mee}{{\M^e_e}}
|
||||
\newcommand{\Mej}{{\M^e_j}}
|
||||
\newcommand{\BigO}[1]{\mathcal{O}\bigl(#1\bigr)}
|
||||
\newcommand{\bE}{\mathbf{E}}
|
||||
\newcommand{\bH}{\mathbf{H}}
|
||||
\newcommand{\B}{\vec{B}}
|
||||
\newcommand{\D}{\vec{D}}
|
||||
\renewcommand{\H}{\vec{H}}
|
||||
\newcommand{\s}{\vec{s}}
|
||||
\newcommand{\bfJ}{\bf{J}}
|
||||
\newcommand{\vecm}{\vec m}
|
||||
\renewcommand{\Re}{\mathsf{Re}}
|
||||
\renewcommand{\Im}{\mathsf{Im}}
|
||||
\renewcommand {\j} { {\vec j} }
|
||||
\newcommand {\h} { {\vec h} }
|
||||
\renewcommand {\b} { {\vec b} }
|
||||
\newcommand {\e} { {\vec e} }
|
||||
\newcommand {\c} { {\vec c} }
|
||||
\renewcommand {\d} { {\vec d} }
|
||||
\renewcommand {\u} { {\vec u} }
|
||||
\newcommand{\I}{\vec{I}}
|
||||
|
||||
|
||||
Time Domain Electromagnetics
|
||||
****************************
|
||||
|
||||
.. _api_TDEM_derivation:
|
||||
|
||||
Time-Domain EM Derivation
|
||||
=========================
|
||||
|
||||
The following shows the derivation for the TDEM problem. We use the b-formulation below.
|
||||
(More to come soon..!)
|
||||
|
||||
|
||||
Sensitivity Calculation
|
||||
-----------------------
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\dcurl \e^{(t+1)} + \frac{\b^{(t+1)} - \b^{(t)}}{\delta t} = 0 \\
|
||||
\dcurl^\top \MfMui \b^{(t+1)} - \MeSig \e^{(t+1)} = \Me \j_s^{(t+1)}
|
||||
\end{align}
|
||||
|
||||
Using Gauss-Newton to solve the inverse problem requires the ability to calculate the product of the
|
||||
Jacobian and a vector, as well as the transpose of the Jacobian times a vector.
|
||||
The above system can be rewritten as:
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\mathbf{A} \u^{(t+1)} + \mathbf{B} \u^{(t)}= \s^{(t+1)}
|
||||
\end{align}
|
||||
|
||||
where
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\mathbf{A} =
|
||||
\left[
|
||||
\begin{array}{cc}
|
||||
\frac{1}{\delta t} \MfMui & \MfMui\dcurl \\
|
||||
\dcurl^\top \MfMui & -\MeSig
|
||||
\end{array}
|
||||
\right] \\
|
||||
\mathbf{B} =
|
||||
\left[
|
||||
\begin{array}{cc}
|
||||
-\frac{1}{\delta t} \MfMui & 0 \\
|
||||
0 & 0
|
||||
\end{array}
|
||||
\right] \\
|
||||
\u^{(k)} = \left[
|
||||
\begin{array}{c}
|
||||
\b^{(k)}\\
|
||||
\e^{(k)}
|
||||
\end{array}
|
||||
\right] \\
|
||||
\s^{(k)} = \left[
|
||||
\begin{array}{c}
|
||||
0\\
|
||||
\Me \j^{(k)}_s
|
||||
\end{array}
|
||||
\right]
|
||||
\end{align}
|
||||
|
||||
.. note::
|
||||
|
||||
Here we have multiplied through by \\(\\MfMui\\) to make A and B symmetric!
|
||||
|
||||
The entire time dependent system can be written in a single matrix expression
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\hat{\mathbf{A}} \hat{u} = \hat{s}
|
||||
\end{align}
|
||||
|
||||
where
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\mathbf{\hat{A}} = \left[
|
||||
\begin{array}{cccc}
|
||||
A & 0 & & \\
|
||||
B & A & & \\
|
||||
& \ddots & \ddots & \\
|
||||
& & B & A
|
||||
\end{array}
|
||||
\right] \\
|
||||
\hat{u} = \left[
|
||||
\begin{array}{c}
|
||||
\u^{(1)} \\
|
||||
\u^{(2)} \\
|
||||
\vdots \\
|
||||
\u^{(N)}
|
||||
\end{array} \right]\\
|
||||
\hat{s} = \left[
|
||||
\begin{array}{c}
|
||||
\s^{(1)} - \mathbf{B} \u^{(0)} \\
|
||||
\s^{(2)} \\
|
||||
\vdots \\
|
||||
\s^{(N)}
|
||||
\end{array}
|
||||
\right]
|
||||
\end{align}
|
||||
|
||||
For the fields \\(\\u\\), the measured data is given by
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\vec{d} = \mathbf{Q} \u
|
||||
\end{align}
|
||||
|
||||
The sensitivity matrix **J** is then defined as
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\mathbf{J} = \mathbf{Q} \frac{\partial \u}{\partial \sigma}
|
||||
\end{align}
|
||||
|
||||
|
||||
Defining the function \\(\\c(m,\\u)\\) to be
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\vec{c}(m,\u) = \hat{\mathbf{A}} \vec{u} - \vec{q} = \vec{0}
|
||||
\end{align}
|
||||
|
||||
then
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{\partial \vec{c}}{\partial m} \partial m
|
||||
+ \frac{\partial \vec{c}}{\partial \u} \partial \vec{u} = 0
|
||||
\end{align}
|
||||
|
||||
or
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{\partial \vec{u}}{\partial m} = -\left(\frac{\partial \vec{c}}{\partial \u} \right)^{-1} \frac{\partial \vec{c}}{\partial m}
|
||||
\end{align}
|
||||
|
||||
|
||||
Differentiating, we find that
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{\partial \vec{c}}{\partial \hat{u}} = \hat{\mathbf{A}}
|
||||
\end{align}
|
||||
|
||||
and
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{\partial \vec{c}}{\partial \sigma} = \mathbf{G}_\sigma =
|
||||
\left[
|
||||
\begin{array}{c}
|
||||
g_\sigma^{(1)}\\
|
||||
g_\sigma^{(2)}\\
|
||||
\vdots \\
|
||||
g_\sigma^{(N)}
|
||||
\end{array}
|
||||
\right]
|
||||
\end{align}
|
||||
|
||||
with
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
g_\sigma^{(n)} =
|
||||
\left[
|
||||
\begin{array}{c}
|
||||
\mathbf{0} \\
|
||||
- \diag{\e^{(n)}} \Ace \diag{\vec{V}}
|
||||
\end{array}
|
||||
\right]
|
||||
\end{align}
|
||||
|
||||
|
||||
Implementing **J** times a vector
|
||||
---------------------------------
|
||||
|
||||
Multiplying **J** onto a vector can be broken into three steps
|
||||
|
||||
|
||||
* Compute \\(\\vec{p} = \\mathbf{G}m\\)
|
||||
* Solve \\(\\hat{\\mathbf{A}} \\vec{y} = \\vec{p}\\)
|
||||
* Compute \\(\\vec{w} = -\\mathbf{Q} \\vec{y}\\)
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\vec{p}^{(n)} = \left[
|
||||
\begin{array}{c}
|
||||
\vec{p}_b^{(n)} \\
|
||||
\vec{p}_e^{(n)}
|
||||
\end{array}
|
||||
\right] \\
|
||||
\vec{p}_b^{(n)} = 0 \\
|
||||
\vec{p}_e^{(n)} = - \diag{\e^{(n)}} \Ace \diag{V} m
|
||||
\end{align}
|
||||
|
||||
|
||||
For all time steps:
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{1}{\delta t} \MfMui\vec{y}_{b}^{(t+1)} + \MfMui\dcurl \vec{y}_{e}^{(t+1)}
|
||||
- \frac{1}{\delta t} \MfMui \vec{y}_{b}^{(t)}
|
||||
= \vec{p}_b^{(t+1)} \\
|
||||
\dcurl^\top \MfMui \vec{y}_b^{(t+1)} - \MeSig \vec{y}_e^{(t+1)} = \vec{p}_e^{(t+1)}
|
||||
\end{align}
|
||||
|
||||
and
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\left( \MfMui \dcurl \MeSig^{-1} \dcurl^\top \MfMui + \frac{1}{\delta t} \MfMui \right) \vec{y}_{b}^{(t+1)} =
|
||||
\frac{1}{\delta t} \MfMui \vec{y}_b^{(t)}
|
||||
+ \MfMui \dcurl \MeSig^{-1} \vec{p}_e^{(t+1)} + \vec{p}_b^{(t+1)} \\
|
||||
\vec{y}_e^{(t+1)} = \MeSig^{-1} \dcurl^\top \MfMui \vec{y}_b^{(t+1)} - \MeSig^{-1} \vec{p}_e^{(t+1)}
|
||||
\end{align}
|
||||
|
||||
.. note::
|
||||
|
||||
For the first time step, \\\(t=0\\\), the term: \\\(\\frac{1}{\\delta t} \\MfMui \\vec{y}_b^{(0)}\\\) is zero.
|
||||
|
||||
|
||||
|
||||
|
||||
Implementing **J** transpose times a vector
|
||||
-------------------------------------------
|
||||
|
||||
Multiplying \\(\\mathbf{J}^\\top\\) onto a vector can be broken into three steps
|
||||
|
||||
|
||||
* Compute \\(\\vec{p} = \\mathbf{Q}^\\top \\vec{v}\\)
|
||||
* Solve \\(\\hat{\\mathbf{A}}^\\top \\vec{y} = \\vec{p}\\)
|
||||
* Compute \\(\\vec{w} = -\\mathbf{G}^\\top y\\)
|
||||
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{\hat{A}}^\top = \left[
|
||||
\begin{array}{cccc}
|
||||
A & B & & \\
|
||||
& \ddots & \ddots & \\
|
||||
& & A & B \\
|
||||
& & 0 & A
|
||||
\end{array}
|
||||
\right]
|
||||
|
||||
For the all time-steps (going backwards in time):
|
||||
|
||||
|
||||
.. math::
|
||||
|
||||
A \vec{y}^{(t)} + B \vec{y}^{(t+1)} = \vec{p}^{(t)}
|
||||
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\frac{1}{\delta t} \MfMui\vec{y}_{b}^{(t)} + \MfMui\dcurl \vec{y}_{e}^{(t)}
|
||||
- \frac{1}{\delta t} \MfMui \vec{y}_{b}^{(t+1)}
|
||||
= \vec{p}_b^{(t)} \\
|
||||
\dcurl^\top \MfMui \vec{y}_b^{(t)} - \MeSig \vec{y}_e^{(t)} = \vec{p}_e^{(t)}
|
||||
\end{align}
|
||||
|
||||
and
|
||||
|
||||
.. math::
|
||||
|
||||
\begin{align}
|
||||
\left( \MfMui \dcurl \MeSig^{-1} \dcurl^\top \MfMui + \frac{1}{\delta t} \MfMui \right) \vec{y}_{b}^{(t)} =
|
||||
\frac{1}{\delta t} \MfMui \vec{y}_b^{(t+1)}
|
||||
+ \MfMui \dcurl \MeSig^{-1} \vec{p}_e^{(t)} + \vec{p}_b^{(t)} \\
|
||||
\vec{y}_e^{(t)} = \MeSig^{-1} \dcurl^\top \MfMui \vec{y}_b^{(t)} - \MeSig^{-1} \vec{p}_e^{(t)}
|
||||
\end{align}
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
For the last time step, \\\(t=N\\\), the term: \\\(\\frac{1}{\\delta t} \\MfMui \\vec{y}_b^{(N+1)}\\\) is zero.
|
||||
|
||||
|
||||
|
||||
TDEM - B formulation
|
||||
====================
|
||||
|
||||
.. automodule:: SimPEG.EM.TDEM.TDEM_b
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Field Storage
|
||||
=============
|
||||
|
||||
.. autoclass:: SimPEG.EM.TDEM.BaseTDEM.FieldsTDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
TDEM Survey Classes
|
||||
===================
|
||||
|
||||
.. autoclass:: SimPEG.EM.TDEM.SurveyTDEM.SurveyTDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
Base Classes
|
||||
============
|
||||
|
||||
.. automodule:: SimPEG.EM.TDEM.BaseTDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
simpegEM Utilities
|
||||
******************
|
||||
|
||||
SimPEG for EM provides a few EM specific utility codes,
|
||||
sources, and analytic functions.
|
||||
|
||||
Utilities for Electromagnetics
|
||||
==============================
|
||||
|
||||
.. automodule:: SimPEG.EM.Utils
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
Analytic Functions - Time
|
||||
=========================
|
||||
|
||||
.. automodule:: SimPEG.EM.Analytics.TDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
|
||||
|
||||
Analytic Functions - Frequency
|
||||
==============================
|
||||
|
||||
.. automodule:: SimPEG.EM.Analytics.FDEM
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -0,0 +1,33 @@
|
||||
Overview of Electromagnetics in SimPEG
|
||||
**************************************
|
||||
|
||||
|
||||
The API
|
||||
=======
|
||||
|
||||
Physical Properties
|
||||
-------------------
|
||||
|
||||
.. autoclass:: SimPEG.EM.Base.EMPropMap
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
Problem
|
||||
-------
|
||||
|
||||
.. autoclass:: SimPEG.EM.Base.BaseEMProblem
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Survey
|
||||
------
|
||||
|
||||
.. autoclass:: SimPEG.EM.Base.BaseEMSurvey
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
Electromagnetics
|
||||
================
|
||||
|
||||
`SimPEG.EM` uses SimPEG as the framework for the forward and inverse
|
||||
electromagnetics geophysical problems.
|
||||
|
||||
To solve for predicted data, we follow the framework shown below. The model is
|
||||
what we invert for. This is mapped to a physical property on the simulation
|
||||
mesh. A source which is used to excite the system is specified. Having a model
|
||||
and a source, we can solve Maxwell's equations for fields. We sample these
|
||||
fields with recievers to give us predicted data.
|
||||
|
||||
|
||||
.. image:: ../../images/simpegEM_noMath.png
|
||||
:scale: 50%
|
||||
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
api_basic
|
||||
api_FDEM
|
||||
api_TDEM
|
||||
api_Utils
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
.. _examples_DC_Analytic_Dipole:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
DC Analytic Dipole
|
||||
==================
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.DC_Analytic_Dipole.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/DC_Analytic_Dipole.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,36 @@
|
||||
.. _examples_DC_Forward_PseudoSection:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
DC Forward Simulation
|
||||
=====================
|
||||
|
||||
Forward model two conductive spheres in a half-space and plot a
|
||||
pseudo-section. Assumes an infinite line source and measures along the
|
||||
center of the spheres.
|
||||
|
||||
INPUT:
|
||||
loc = Location of spheres [[x1,y1,z1],[x2,y2,z2]]
|
||||
radi = Radius of spheres [r1,r2]
|
||||
param = Conductivity of background and two spheres [m0,m1,m2]
|
||||
surveyType = survey type 'pole-dipole' or 'dipole-dipole'
|
||||
unitType = Data type "appResistivity" | "appConductivity" | "volt"
|
||||
Created by @fourndo
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.DC_Forward_PseudoSection.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/DC_Forward_PseudoSection.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_EM_FDEM_1D_Inversion:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
EM: FDEM: 1D: Inversion
|
||||
=======================
|
||||
|
||||
Here we will create and run a FDEM 1D inversion.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.EM_FDEM_1D_Inversion.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/EM_FDEM_1D_Inversion.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_EM_FDEM_Analytic_MagDipoleWholespace:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
EM: Magnetic Dipole in a Whole-Space
|
||||
====================================
|
||||
|
||||
Here we plot the magnetic flux density from a harmonic dipole in a wholespace.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.EM_FDEM_Analytic_MagDipoleWholespace.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/EM_FDEM_Analytic_MagDipoleWholespace.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,61 @@
|
||||
.. _examples_EM_Schenkel_Morrison_Casing:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
EM: Schenkel and Morrison Casing Model
|
||||
======================================
|
||||
|
||||
Here we create and run a FDEM forward simulation to calculate the vertical
|
||||
current inside a steel-cased. The model is based on the Schenkel and
|
||||
Morrison Casing Model, and the results are used in a 2016 SEG abstract by
|
||||
Yang et al.
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
Schenkel, C.J., and H.F. Morrison, 1990, Effects of well casing on potential field measurements using downhole current sources: Geophysical prospecting, 38, 663-686.
|
||||
|
||||
|
||||
The model consists of:
|
||||
|
||||
- Air: Conductivity 1e-8 S/m, above z = 0
|
||||
- Background: conductivity 1e-2 S/m, below z = 0
|
||||
- Casing: conductivity 1e6 S/m
|
||||
- 300m long
|
||||
- radius of 0.1m
|
||||
- thickness of 6e-3m
|
||||
|
||||
Inside the casing, we take the same conductivity as the background.
|
||||
|
||||
We are using an EM code to simulate DC, so we use frequency low enough
|
||||
that the skin depth inside the casing is longer than the casing length (f
|
||||
= 1e-6 Hz). The plot produced is of the current inside the casing.
|
||||
|
||||
These results are shown in the SEG abstract by Yang et al., 2016: 3D DC
|
||||
resistivity modeling of steel casing for reservoir monitoring using
|
||||
equivalent resistor network. The solver used to produce these results and
|
||||
achieve the CPU time of ~30s is Mumps, which was installed using pymatsolver_
|
||||
|
||||
.. _pymatsolver: https://github.com/rowanc1/pymatsolver
|
||||
|
||||
This example is on figshare: https://dx.doi.org/10.6084/m9.figshare.3126961.v1
|
||||
|
||||
If you would use this example for a code comparison, or build upon it, a
|
||||
citation would be much appreciated!
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.EM_Schenkel_Morrison_Casing.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/EM_Schenkel_Morrison_Casing.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_EM_TDEM_1D_Inversion:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
EM: TDEM: 1D: Inversion
|
||||
=======================
|
||||
|
||||
Here we will create and run a TDEM 1D inversion.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.EM_TDEM_1D_Inversion.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/EM_TDEM_1D_Inversion.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,52 @@
|
||||
.. _examples_FLOW_Richards_1D_Celia1990:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
FLOW: Richards: 1D: Celia1990
|
||||
=============================
|
||||
|
||||
There are two different forms of Richards equation that differ
|
||||
on how they deal with the non-linearity in the time-stepping term.
|
||||
|
||||
The most fundamental form, referred to as the
|
||||
'mixed'-form of Richards Equation Celia1990_
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \theta(\psi)}{\partial t} - \nabla \cdot k(\psi) \nabla \psi - \frac{\partial k(\psi)}{\partial z} = 0
|
||||
\quad \psi \in \Omega
|
||||
|
||||
where \\(\\theta\\) is water content, and \\(\\psi\\) is pressure head.
|
||||
This formulation of Richards equation is called the
|
||||
'mixed'-form because the equation is parameterized in \\(\\psi\\)
|
||||
but the time-stepping is in terms of \\(\\theta\\).
|
||||
|
||||
As noted in Celia1990_ the 'head'-based form of Richards
|
||||
equation can be written in the continuous form as:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \theta}{\partial \psi}\frac{\partial \psi}{\partial t} - \nabla \cdot k(\psi) \nabla \psi - \frac{\partial k(\psi)}{\partial z} = 0 \quad \psi \in \Omega
|
||||
|
||||
However, it can be shown that this does not conserve mass in the discrete formulation.
|
||||
|
||||
Here we reproduce the results from Celia1990_ demonstrating the head-based formulation and the mixed-formulation.
|
||||
|
||||
.. _Celia1990: http://www.webpages.uidaho.edu/ch/papers/Celia.pdf
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.FLOW_Richards_1D_Celia1990.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/FLOW_Richards_1D_Celia1990.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_Inversion_Linear:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Inversion: Linear Problem
|
||||
=========================
|
||||
|
||||
Here we go over the basics of creating a linear problem and inversion.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Inversion_Linear.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Inversion_Linear.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,27 @@
|
||||
.. _examples_MT_1D_ForwardAndInversion:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
MT: 1D: Inversion
|
||||
=================
|
||||
|
||||
Forward model 1D MT data.
|
||||
Setup and run a MT 1D inversion.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.MT_1D_ForwardAndInversion.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/MT_1D_ForwardAndInversion.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_MT_3D_Foward:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
MT: 3D: Forward
|
||||
===============
|
||||
|
||||
Forward model 3D MT data.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.MT_3D_Foward.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/MT_3D_Foward.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,25 @@
|
||||
.. _examples_Mesh_Basic_ForwardDC:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: Basic Forward 2D DC Resistivity
|
||||
=====================================
|
||||
|
||||
2D DC forward modeling example with Tensor and Curvilinear Meshes
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Basic_ForwardDC.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_Basic_ForwardDC.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,27 @@
|
||||
.. _examples_Mesh_Basic_PlotImage:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: Basic: PlotImage
|
||||
======================
|
||||
|
||||
You can use M.PlotImage to plot images on all of the Meshes.
|
||||
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Basic_PlotImage.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_Basic_PlotImage.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_Mesh_Basic_Types:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: Basic: Types
|
||||
==================
|
||||
|
||||
Here we show SimPEG used to create three different types of meshes.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Basic_Types.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_Basic_Types.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,57 @@
|
||||
.. _examples_Mesh_Operators_CahnHilliard:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: Operators: Cahn Hilliard
|
||||
==============================
|
||||
|
||||
This example is based on the example in the FiPy_ library.
|
||||
Please see their documentation for more information about the Cahn-Hilliard equation.
|
||||
|
||||
The "Cahn-Hilliard" equation separates a field \\( \\phi \\) into 0 and 1 with smooth transitions.
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \phi}{\partial t} = \nabla \cdot D \nabla \left( \frac{\partial f}{\partial \phi} - \epsilon^2 \nabla^2 \phi \right)
|
||||
|
||||
Where \\( f \\) is the energy function \\( f = ( a^2 / 2 )\\phi^2(1 - \\phi)^2 \\)
|
||||
which drives \\( \\phi \\) towards either 0 or 1, this competes with the term
|
||||
\\(\\epsilon^2 \\nabla^2 \\phi \\) which is a diffusion term that creates smooth changes in \\( \\phi \\).
|
||||
The equation can be factored:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \phi}{\partial t} = \nabla \cdot D \nabla \psi \\
|
||||
\psi = \frac{\partial^2 f}{\partial \phi^2} (\phi - \phi^{\text{old}}) + \frac{\partial f}{\partial \phi} - \epsilon^2 \nabla^2 \phi
|
||||
|
||||
Here we will need the derivatives of \\( f \\):
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial f}{\partial \phi} = (a^2/2)2\phi(1-\phi)(1-2\phi)
|
||||
\frac{\partial^2 f}{\partial \phi^2} = (a^2/2)2[1-6\phi(1-\phi)]
|
||||
|
||||
The implementation below uses backwards Euler in time with an exponentially increasing time step.
|
||||
The initial \\( \\phi \\) is a normally distributed field with a standard deviation of 0.1 and mean of 0.5.
|
||||
The grid is 60x60 and takes a few seconds to solve ~130 times. The results are seen below, and you can see the
|
||||
field separating as the time increases.
|
||||
|
||||
.. _FiPy: http://www.ctcms.nist.gov/fipy/examples/cahnHilliard/generated/examples.cahnHilliard.mesh2DCoupled.html
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Operators_CahnHilliard.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_Operators_CahnHilliard.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,31 @@
|
||||
.. _examples_Mesh_QuadTree_Creation:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: QuadTree: Creation
|
||||
========================
|
||||
|
||||
You can give the refine method a function, which is evaluated on every cell
|
||||
of the TreeMesh.
|
||||
|
||||
Occasionally it is useful to initially refine to a constant level
|
||||
(e.g. 3 in this 32x32 mesh). This means the function is first evaluated
|
||||
on an 8x8 mesh (2^3).
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_QuadTree_Creation.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_QuadTree_Creation.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,26 @@
|
||||
.. _examples_Mesh_QuadTree_FaceDiv:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: QuadTree: FaceDiv
|
||||
=======================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_QuadTree_FaceDiv.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_QuadTree_FaceDiv.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,31 @@
|
||||
.. _examples_Mesh_QuadTree_HangingNodes:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
Mesh: QuadTree: Hanging Nodes
|
||||
=============================
|
||||
|
||||
You can give the refine method a function, which is evaluated on every cell
|
||||
of the TreeMesh.
|
||||
|
||||
Occasionally it is useful to initially refine to a constant level
|
||||
(e.g. 3 in this 32x32 mesh). This means the function is first evaluated
|
||||
on an 8x8 mesh (2^3).
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_QuadTree_HangingNodes.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_QuadTree_HangingNodes.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,43 @@
|
||||
.. _examples_Mesh_Tensor_Creation:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
|
||||
Mesh: Tensor: Creation
|
||||
======================
|
||||
|
||||
For tensor meshes, there are some functions that can come
|
||||
in handy. For example, creating mesh tensors can be a bit time
|
||||
consuming, these can be created speedily by just giving numbers
|
||||
and sizes of padding. See the example below, that follows this
|
||||
notation::
|
||||
|
||||
h1 = (
|
||||
(cellSize, numPad, [, increaseFactor]),
|
||||
(cellSize, numCore),
|
||||
(cellSize, numPad, [, increaseFactor])
|
||||
)
|
||||
|
||||
.. note::
|
||||
|
||||
You can center your mesh by passing a 'C' for the x0[i] position.
|
||||
A 'N' will make the entire mesh negative, and a '0' (or a 0) will
|
||||
make the mesh start at zero.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Mesh_Tensor_Creation.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Mesh_Tensor_Creation.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,28 @@
|
||||
.. _examples_Utils_surface2ind_topo:
|
||||
|
||||
.. --------------------------------- ..
|
||||
.. ..
|
||||
.. THIS FILE IS AUTO GENEREATED ..
|
||||
.. ..
|
||||
.. SimPEG/Examples/__init__.py ..
|
||||
.. ..
|
||||
.. --------------------------------- ..
|
||||
|
||||
|
||||
|
||||
Utils: surface2ind_topo
|
||||
=======================
|
||||
|
||||
Here we show how to use :code:`Utils.surface2ind_topo` to identify cells below
|
||||
a topographic surface.
|
||||
|
||||
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.Utils_surface2ind_topo.run()
|
||||
|
||||
.. literalinclude:: ../../SimPEG/Examples/Utils_surface2ind_topo.py
|
||||
:language: python
|
||||
:linenos:
|
||||
@@ -0,0 +1,47 @@
|
||||
.. _api_Richards:
|
||||
|
||||
|
||||
Richards Equation
|
||||
*****************
|
||||
|
||||
There are two different forms of Richards equation that differ
|
||||
on how they deal with the non-linearity in the time-stepping term.
|
||||
|
||||
The most fundamental form, referred to as the
|
||||
'mixed'-form of Richards Equation [Celia et al., 1990]
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \theta(\psi)}{\partial t} - \nabla \cdot k(\psi) \nabla \psi - \frac{\partial k(\psi)}{\partial z} = 0
|
||||
\quad \psi \in \Omega
|
||||
|
||||
where theta is water content, and psi is pressure head.
|
||||
This formulation of Richards equation is called the
|
||||
'mixed'-form because the equation is parameterized in psi
|
||||
but the time-stepping is in terms of theta.
|
||||
|
||||
As noted in [Celia et al., 1990] the 'head'-based form of Richards
|
||||
equation can be written in the continuous form as:
|
||||
|
||||
.. math::
|
||||
|
||||
\frac{\partial \theta}{\partial \psi}\frac{\partial \psi}{\partial t} - \nabla \cdot k(\psi) \nabla \psi - \frac{\partial k(\psi)}{\partial z} = 0
|
||||
\quad \psi \in \Omega
|
||||
|
||||
However, it can be shown that this does not conserve mass in the discrete formulation.
|
||||
|
||||
|
||||
Here we reproduce the results from Celia et al. (1990):
|
||||
|
||||
.. plot::
|
||||
|
||||
from SimPEG import Examples
|
||||
Examples.FLOW_Richards_1D_Celia1990.run()
|
||||
|
||||
Richards
|
||||
========
|
||||
|
||||
.. automodule:: SimPEG.FLOW.Richards.Empirical
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
@@ -0,0 +1,14 @@
|
||||
Induced Polarization
|
||||
********************
|
||||
|
||||
Todo: docs for IP!
|
||||
|
||||
|
||||
API for IP codes
|
||||
================
|
||||
|
||||
.. automodule:: SimPEG.DCIP.BaseIP
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
:inherited-members:
|
||||
@@ -0,0 +1,19 @@
|
||||
Magnetotellurics
|
||||
****************
|
||||
|
||||
SimPEG (Simulation and Parameter Estimation in Geophysics) is a python
|
||||
package for simulation and gradient based parameter estimation in the
|
||||
context of geoscience applications.
|
||||
|
||||
simpegMT uses SimPEG as the framework for the forward and inverse
|
||||
magnetotellurics geophysical problems.
|
||||
|
||||
|
||||
|
||||
Problem
|
||||
=======
|
||||
|
||||
.. autoclass:: SimPEG.MT.BaseMT.BaseMTProblem
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
Reference in New Issue
Block a user