From 2c5b19b7a09210483c8706e79f2d6cd7780d7124 Mon Sep 17 00:00:00 2001 From: Rowan Cockett Date: Sun, 10 Jan 2016 17:21:01 -0800 Subject: [PATCH] Updates to the documentation. --- AUTHORS.rst | 10 +- CITATION.rst | 5 +- LICENSE | 2 +- PROJECTS.rst | 36 ----- SimPEG/EM/Analytics/FDEM.py | 3 +- SimPEG/Regularization.py | 83 +---------- docs/InversionWorkflow-PreSimPEG.png | Bin 0 -> 50417 bytes docs/api_FiniteVolume.rst | 19 +++ docs/api_ForwardProblem.rst | 7 +- docs/{api_Inverse.rst => api_Inversion.rst} | 23 +-- docs/api_InversionComponents.rst | 11 ++ docs/api_Mesh.rst | 3 +- docs/api_MeshCode.rst | 20 +-- docs/api_Optimization.rst | 9 ++ docs/api_Regularization.rst | 100 +++++++++++++ docs/api_Utilities.rst | 10 ++ docs/api_Utils.rst | 9 +- docs/api_bigPicture.rst | 64 ++++++++- docs/api_installing.rst | 4 +- docs/api_license.rst | 17 --- docs/em/api_Utils.rst | 7 +- docs/em/index.rst | 5 +- docs/index.rst | 151 +++++++++----------- 23 files changed, 316 insertions(+), 282 deletions(-) delete mode 100644 PROJECTS.rst create mode 100644 docs/InversionWorkflow-PreSimPEG.png create mode 100644 docs/api_FiniteVolume.rst rename docs/{api_Inverse.rst => api_Inversion.rst} (56%) create mode 100644 docs/api_InversionComponents.rst create mode 100644 docs/api_Optimization.rst create mode 100644 docs/api_Regularization.rst create mode 100644 docs/api_Utilities.rst delete mode 100644 docs/api_license.rst diff --git a/AUTHORS.rst b/AUTHORS.rst index 2a7d1903..f5e5ff7b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -1,9 +1,13 @@ -- Luz Angelica Caudillo-Mata, (`@lacmajedrez `_) - Rowan Cockett, (`@rowanc1 `_) -- Eldad Haber, (`@ehaber99 `_) - Lindsey Heagy, (`@lheagy `_) - Seogi Kang, (`@sgkang `_) -- Dave Marchant, (`@dwfmarchant `_) +- Brendan Smithyman, (`@bsmithyman `_) - Gudni Rosenkjaer, (`@grosenkj `_) +- Dom Fournier, (`@fourndo `_) +- Dave Marchant, (`@dwfmarchant `_) - Lars Ruthotto, (`@lruthotto `_) - Mike Wathen, (`@mrwathen `_) +- Luz Angelica Caudillo-Mata, (`@lacmajedrez `_) +- Eldad Haber, (`@ehaber99 `_) +- Doug Oldenburg, (`@dougoldenburg `_) +- Adam Pidlisecky, (`@aPid1 `_) diff --git a/CITATION.rst b/CITATION.rst index a3a13d7e..b0b2a76f 100644 --- a/CITATION.rst +++ b/CITATION.rst @@ -1,14 +1,13 @@ Citing SimPEG -============= +------------- -There is a paper about SimPEG! +There is a `paper about SimPEG `_, if you use this code, please help our scientific visibility by citing our work! Cockett, R., Kang, S., Heagy, L. J., Pidlisecky, A., & Oldenburg, D. W. (2015). SimPEG: An open source framework for simulation and gradient based parameter estimation in geophysical applications. Computers & Geosciences. BibTex: -------- .. code:: diff --git a/LICENSE b/LICENSE index 43ee31ab..c046b35d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2015 SimPEG Developers +Copyright (c) 2013-2016 SimPEG Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/PROJECTS.rst b/PROJECTS.rst deleted file mode 100644 index ce411d9d..00000000 --- a/PROJECTS.rst +++ /dev/null @@ -1,36 +0,0 @@ -- Electromagnetics (`simpegEM `_) - .. image:: https://travis-ci.org/simpeg/simpegem.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegem - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegem/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegem?branch=master -- Potential Fields (`simpegPF `_) - .. image:: https://travis-ci.org/simpeg/simpegpf.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegpf - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegpf/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegpf?branch=master -- Ground Water Flow (`simpegFLOW `_) - .. image:: https://travis-ci.org/simpeg/simpegflow.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegflow - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegflow/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegflow?branch=master -- Direct Current Resistivity (`simpegDC `_) - .. image:: https://travis-ci.org/simpeg/simpegdc.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegdc - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegdc/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegdc?branch=master -- Electromagnetics 1D (`simpegEM1D `_) - .. image:: https://travis-ci.org/simpeg/simpegEM1D.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegEM1D - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegEM1D/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegEM1D?branch=master -- Magnetotellurics (`simpegMT `_) - .. image:: https://travis-ci.org/simpeg/simpegmt.svg?branch=master - :target: https://travis-ci.org/simpeg/simpegmt - :alt: Master Branch - .. image:: https://coveralls.io/repos/simpeg/simpegmt/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpegmt?branch=master diff --git a/SimPEG/EM/Analytics/FDEM.py b/SimPEG/EM/Analytics/FDEM.py index 9e776fdf..1f52459c 100644 --- a/SimPEG/EM/Analytics/FDEM.py +++ b/SimPEG/EM/Analytics/FDEM.py @@ -58,8 +58,9 @@ def MagneticDipoleWholeSpace(XYZ, srcLoc, sig, f, moment=1., orientation='X', mu from SimPEG import EM import matplotlib.pyplot as plt + from scipy.constants import mu_0 freqs = np.logspace(-2,5,100) - Bx, By, Bz = EM.Analytics.FDEM.AnalyticMagDipoleWholeSpace([0,100,0], [0,0,0], 1e-2, freqs, m=1, orientation='Z') + Bx, By, Bz = EM.Analytics.FDEM.MagneticDipoleWholeSpace([0,100,0], [0,0,0], 1e-2, freqs, moment=1, orientation='Z') plt.loglog(freqs, np.abs(Bz.real)/mu_0, 'b') plt.loglog(freqs, np.abs(Bz.imag)/mu_0, 'r') plt.legend(('real','imag')) diff --git a/SimPEG/Regularization.py b/SimPEG/Regularization.py index e3506290..97b5e7a2 100644 --- a/SimPEG/Regularization.py +++ b/SimPEG/Regularization.py @@ -115,86 +115,7 @@ class BaseRegularization(object): class Tikhonov(BaseRegularization): - """**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} - - + """ """ smoothModel = True #: SMOOTH and SMOOTH_MOD_DIF options alpha_s = Utils.dependentProperty('_alpha_s', 1e-6, ['_W', '_Ws'], "Smallness weight") @@ -311,7 +232,7 @@ class Tikhonov(BaseRegularization): if self.smoothModel == True: mD1 = self.mapping.deriv(m) mD2 = self.mapping.deriv(m - self.mref) - r1 = self.Wsmooth * ( self.mapping * (m)) + r1 = self.Wsmooth * ( self.mapping * (m)) r2 = self.Ws * ( self.mapping * (m - self.mref) ) out1 = mD1.T * ( self.Wsmooth.T * r1 ) out2 = mD2.T * ( self.Ws.T * r2 ) diff --git a/docs/InversionWorkflow-PreSimPEG.png b/docs/InversionWorkflow-PreSimPEG.png new file mode 100644 index 0000000000000000000000000000000000000000..2396da691b2bf1c130e2451e50da5c4f6ea17630 GIT binary patch literal 50417 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 literal 0 HcmV?d00001 diff --git a/docs/api_FiniteVolume.rst b/docs/api_FiniteVolume.rst new file mode 100644 index 00000000..40e9b879 --- /dev/null +++ b/docs/api_FiniteVolume.rst @@ -0,0 +1,19 @@ +.. _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 `_). 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 diff --git a/docs/api_ForwardProblem.rst b/docs/api_ForwardProblem.rst index b8f2fd90..0bf9596f 100644 --- a/docs/api_ForwardProblem.rst +++ b/docs/api_ForwardProblem.rst @@ -61,11 +61,6 @@ If the forward problem is invertible, then we can rearrange for \\(\\frac{\\part This can often be computed given a vector (i.e. \\(J(v)\\)) rather than stored, as \\(J\\) is a large dense matrix. -.. math:: - - u(m) - - The API ======= @@ -78,7 +73,7 @@ Problem Survey ------ - .. automodule:: SimPEG.Survey :members: + :undoc-members: diff --git a/docs/api_Inverse.rst b/docs/api_Inversion.rst similarity index 56% rename from docs/api_Inverse.rst rename to docs/api_Inversion.rst index bd4d8704..5cac5f0c 100644 --- a/docs/api_Inverse.rst +++ b/docs/api_Inversion.rst @@ -1,21 +1,19 @@ -.. _api_Inverse: -Regularization -************** +InvProblem +********** -.. automodule:: SimPEG.Regularization +.. automodule:: SimPEG.InvProblem :show-inheritance: :members: :undoc-members: -Optimize -******** +Inversion +********* -.. automodule:: SimPEG.Optimization +.. automodule:: SimPEG.Inversion :show-inheritance: - :private-members: :members: :undoc-members: @@ -27,12 +25,3 @@ Directives :members: :undoc-members: -Inversion -********* - -.. automodule:: SimPEG.Inversion - :show-inheritance: - :members: - :undoc-members: - - diff --git a/docs/api_InversionComponents.rst b/docs/api_InversionComponents.rst new file mode 100644 index 00000000..eeaf1bbf --- /dev/null +++ b/docs/api_InversionComponents.rst @@ -0,0 +1,11 @@ +Inversion Components +******************** + +.. toctree:: + :maxdepth: 3 + + api_DataMisfit + api_Regularization + api_Optimization + api_Inversion + diff --git a/docs/api_Mesh.rst b/docs/api_Mesh.rst index a7f7abae..ed216b13 100644 --- a/docs/api_Mesh.rst +++ b/docs/api_Mesh.rst @@ -24,8 +24,7 @@ the implementations. .. plot:: from SimPEG import Examples - Examples.Mesh_ThreeMeshes.run() - + Examples.Mesh_Basic_Types.run() Variable Locations and Terminology diff --git a/docs/api_MeshCode.rst b/docs/api_MeshCode.rst index a3813c13..2d7cab9f 100644 --- a/docs/api_MeshCode.rst +++ b/docs/api_MeshCode.rst @@ -9,6 +9,15 @@ Tensor Mesh :undoc-members: +Cylindrical Mesh +================ + +.. automodule:: SimPEG.Mesh.CylMesh + :show-inheritance: + :members: + :undoc-members: + + Tree Mesh ========= @@ -21,16 +30,7 @@ Tree Mesh Curvilinear Mesh ================ -.. automodule:: SimPEG.Mesh.Curvilinear - :show-inheritance: - :members: - :undoc-members: - - -Cylindrical Mesh -================ - -.. automodule:: SimPEG.Mesh.CylMesh +.. automodule:: SimPEG.Mesh.CurvilinearMesh :show-inheritance: :members: :undoc-members: diff --git a/docs/api_Optimization.rst b/docs/api_Optimization.rst new file mode 100644 index 00000000..85ec523f --- /dev/null +++ b/docs/api_Optimization.rst @@ -0,0 +1,9 @@ + +Optimize +******** + +.. automodule:: SimPEG.Optimization + :show-inheritance: + :private-members: + :members: + :undoc-members: diff --git a/docs/api_Regularization.rst b/docs/api_Regularization.rst new file mode 100644 index 00000000..4ea1a554 --- /dev/null +++ b/docs/api_Regularization.rst @@ -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: + + + diff --git a/docs/api_Utilities.rst b/docs/api_Utilities.rst new file mode 100644 index 00000000..c3a08b30 --- /dev/null +++ b/docs/api_Utilities.rst @@ -0,0 +1,10 @@ +Utilities +********* + +.. toctree:: + :maxdepth: 2 + + api_Solver + api_Maps + api_Utils + api_Tests diff --git a/docs/api_Utils.rst b/docs/api_Utils.rst index 042aef67..1bf86516 100644 --- a/docs/api_Utils.rst +++ b/docs/api_Utils.rst @@ -1,8 +1,5 @@ -.. _api_Utils: - - -Utilities -********* +Utils +***** .. automodule:: SimPEG.Utils :members: @@ -52,7 +49,7 @@ Interpolation Utilities :undoc-members: Counter Utilities -======================= +================= :: class MyClass(object): diff --git a/docs/api_bigPicture.rst b/docs/api_bigPicture.rst index ef7c1174..90266650 100644 --- a/docs/api_bigPicture.rst +++ b/docs/api_bigPicture.rst @@ -1,17 +1,69 @@ -.. _api_license: - 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:: 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:: 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`) 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. -Explaining The Big Picture -========================== +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`) 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`) 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 diff --git a/docs/api_installing.rst b/docs/api_installing.rst index e0e7ab59..23938dee 100644 --- a/docs/api_installing.rst +++ b/docs/api_installing.rst @@ -1,7 +1,7 @@ .. _api_installing: -Installation -************ +Getting Started with SimPEG +*************************** Dependencies ============ diff --git a/docs/api_license.rst b/docs/api_license.rst deleted file mode 100644 index b8f2d439..00000000 --- a/docs/api_license.rst +++ /dev/null @@ -1,17 +0,0 @@ -.. _api_license: - -License -******* - -.. include:: ../LICENSE - -Authors -******* - -.. include:: ../AUTHORS.rst - - -Projects Using SimPEG -********************* - -.. include:: ../PROJECTS.rst diff --git a/docs/em/api_Utils.rst b/docs/em/api_Utils.rst index b7e9ea45..8ae98855 100644 --- a/docs/em/api_Utils.rst +++ b/docs/em/api_Utils.rst @@ -7,7 +7,7 @@ sources, and analytic functions. Analytic Functions - Time ========================= -.. automodule:: SimPEG.EM.Utils.Ana.TEM +.. automodule:: SimPEG.EM.Analytics.TDEM :show-inheritance: :members: :undoc-members: @@ -17,7 +17,7 @@ Analytic Functions - Time Analytic Functions - Frequency ============================== -.. automodule:: SimPEG.EM.Utils.Ana.FEM +.. automodule:: SimPEG.EM.Analytics.FDEM :show-inheritance: :members: :undoc-members: @@ -27,8 +27,7 @@ Analytic Functions - Frequency Sources ======= -.. automodule:: SimPEG.EM.Utils.Sources.magneticDipole +.. autoclass:: SimPEG.EM.FDEM.SrcFDEM.MagDipole :show-inheritance: :members: :undoc-members: - :inherited-members: diff --git a/docs/em/index.rst b/docs/em/index.rst index 8cbb8619..fdf4dc19 100644 --- a/docs/em/index.rst +++ b/docs/em/index.rst @@ -9,7 +9,7 @@ Time Domian Electromagnetics ---------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 2 api_TDEM_derivation @@ -18,7 +18,7 @@ Code for Time Domian Electromagnetics ------------------------------------- .. toctree:: - :maxdepth: 2 + :maxdepth: 2 api_TDEM @@ -28,7 +28,6 @@ Frequency Domian Electromagnetics .. toctree:: :maxdepth: 2 - api_ForwardProblem api_FDEM diff --git a/docs/index.rst b/docs/index.rst index d3ec4e8c..be173aae 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,25 +1,38 @@ +.. image:: https://raw.github.com/simpeg/simpeg/master/docs/simpeg-logo.png + :alt: SimPEG Logo + SimPEG Documentation ******************** -.. image:: simpeg-logo.png - :width: 300 px - :alt: SimPEG - :align: center +.. image:: https://img.shields.io/pypi/v/SimPEG.svg + :target: https://crate.io/packages/SimPEG/ + :alt: Latest PyPI version -SimPEG: Simulation and Parameter Estimation in Geophysics +.. image:: https://img.shields.io/pypi/dm/SimPEG.svg + :target: https://crate.io/packages/SimPEG/ + :alt: Number of PyPI downloads -SimPEG is a framework and a collection of tools that aid in the development of -large-scale geophysical inversion codes. -The vision is to create a modular and extensible package for -finite volume simulation and parameter estimation with -applications to geophysical imaging and subsurface flow. To enable -these goals, this package has the following features: +.. image:: https://img.shields.io/badge/license-MIT-blue.svg + :target: https://github.com/simpeg/simpeg/blob/master/LICENSE + :alt: BSD 3 clause license. -- is modular with respect to ... everything! -- is built with the (large-scale) inverse problem in mind -- provides a framework for geophysical and hydrogeologic problems -- supports 1D, 2D and 3D problems -- provides a set of commonly used visualization utilities +.. image:: https://img.shields.io/travis/simpeg/simpeg.svg + :target: https://travis-ci.org/simpeg/simpeg + :alt: Travis CI build status + +.. image:: https://img.shields.io/coveralls/simpeg/simpeg.svg + :target: https://coveralls.io/r/simpeg/simpeg?branch=master + :alt: Coverage status + +Simulation and Parameter Estimation in Geophysics - A python package for simulation and gradient based parameter estimation in the context of geophysical applications. + +Our vision is to create a package for finite volume simulation with applications to geophysical imaging and subsurface flow. To enable the understanding of the many different components, this package has the following features: + +* modular with respect to the spacial discretization, optimization routine, and geophysical problem +* built with the inverse problem in mind +* provides a framework for geophysical and hydrogeologic problems +* supports 1D, 2D and 3D problems +* designed for large-scale inversions About SimPEG @@ -29,56 +42,8 @@ About SimPEG :maxdepth: 2 api_bigPicture - api_license - - -Getting Started with SimPEG -*************************** - -.. toctree:: - :maxdepth: 2 - api_installing -Discretization -************** - -.. toctree:: - :maxdepth: 3 - - api_Mesh - api_DiffOps - api_InnerProducts - -Forward Problems -**************** - -.. toctree:: - :maxdepth: 2 - - api_ForwardProblem - -Inversion -********* - -.. toctree:: - :maxdepth: 3 - - api_DataMisfit - api_Inverse - -Utility Codes -************* - -.. toctree:: - :maxdepth: 2 - - api_Solver - api_Maps - api_Utils - api_Tests - - Packages ******** @@ -88,20 +53,46 @@ Packages em/index flow/index -Developer's Documentation -************************* +Examples +******** -* Travis-CI Testing - .. image:: https://travis-ci.org/simpeg/simpeg.svg?branch=master - :target: https://travis-ci.org/simpeg/simpeg - :alt: Master Branch - :align: center +.. toctree:: + :maxdepth: 2 -* Coveralls Testing - .. image:: https://coveralls.io/repos/simpeg/simpeg/badge.png?branch=master - :target: https://coveralls.io/r/simpeg/simpeg?branch=master - :alt: Coveralls - :align: center + api_Examples + + +Finite Volume +************* + +.. toctree:: + :maxdepth: 3 + + api_FiniteVolume + +Forward Problems +**************** + +.. toctree:: + :maxdepth: 3 + + api_ForwardProblem + +Inversion Components +******************** + +.. toctree:: + :maxdepth: 3 + + api_InversionComponents + +Utility Codes +************* + +.. toctree:: + :maxdepth: 3 + + api_Utilities Project Index & Search @@ -110,11 +101,3 @@ Project Index & Search * :ref:`genindex` * :ref:`modindex` * :ref:`search` - -Examples -******** - -.. toctree:: - :maxdepth: 2 - - api_Examples