Merge branch 'master' into em/dev

This commit is contained in:
Lindsey Heagy
2016-01-15 10:53:22 -08:00
70 changed files with 1324 additions and 1352 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
[bumpversion]
current_version = 0.1.3
current_version = 0.1.9
files = setup.py SimPEG/__init__.py docs/conf.py
+18 -8
View File
@@ -4,17 +4,24 @@ python:
sudo: false
addons:
apt:
packages:
- gcc
- gfortran
- libopenmpi-dev
- libmumps-seq-dev
- libblas-dev
- liblapack-dev
env:
- TEST_DIR=tests/em/examples
- TEST_DIR=tests/em/fdem/forward
- TEST_DIR="tests/mesh tests/base tests/utils"
- TEST_DIR=tests/em/fdem/inverse/derivs
- TEST_DIR=tests/em/fdem/inverse/adjoint
- TEST_DIR=tests/em/tdem
- TEST_DIR=tests/mesh
- TEST_DIR=tests/flow
- TEST_DIR=tests/utils
- TEST_DIR=tests/base
- TEST_DIR=tests/examples
- TEST_DIR=tests/em/fdem/inverse/adjoint
- TEST_DIR=tests/em/fdem/forward
# Setup anaconda
before_install:
@@ -26,9 +33,12 @@ before_install:
# Install packages
install:
- conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython
- conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython nose
- pip install nose-cov python-coveralls
# - pip install -r requirements.txt
- git clone https://github.com/rowanc1/pymatsolver.git
- cd pymatsolver; python setup.py install; cd ..
- python setup.py install
- python setup.py build_ext --inplace
+7 -3
View File
@@ -1,9 +1,13 @@
- Luz Angelica Caudillo-Mata, (`@lacmajedrez <https://github.com/lacmajedrez/>`_)
- Rowan Cockett, (`@rowanc1 <https://github.com/rowanc1/>`_)
- Eldad Haber, (`@ehaber99 <https://github.com/ehaber99/>`_)
- Lindsey Heagy, (`@lheagy <https://github.com/lheagy/>`_)
- Seogi Kang, (`@sgkang <https://github.com/sgkang/>`_)
- Dave Marchant, (`@dwfmarchant <https://github.com/dwfmarchant/>`_)
- Brendan Smithyman, (`@bsmithyman <https://github.com/bsmithyman/>`_)
- Gudni Rosenkjaer, (`@grosenkj <https://github.com/grosenkj/>`_)
- Dom Fournier, (`@fourndo <https://github.com/fourndo/>`_)
- Dave Marchant, (`@dwfmarchant <https://github.com/dwfmarchant/>`_)
- Lars Ruthotto, (`@lruthotto <https://github.com/lruthotto/>`_)
- Mike Wathen, (`@mrwathen <https://github.com/mrwathen/>`_)
- Luz Angelica Caudillo-Mata, (`@lacmajedrez <https://github.com/lacmajedrez/>`_)
- Eldad Haber, (`@ehaber99 <https://github.com/ehaber99/>`_)
- Doug Oldenburg, (`@dougoldenburg <https://github.com/dougoldenburg/>`_)
- Adam Pidlisecky, (`@aPid1 <https://github.com/aPid1/>`_)
+2 -3
View File
@@ -1,14 +1,13 @@
Citing SimPEG
=============
-------------
There is a paper about SimPEG!
There is a `paper about SimPEG <http://dx.doi.org/10.1016/j.cageo.2015.09.015>`_, 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::
-470
View File
@@ -1,470 +0,0 @@
#!/usr/bin/python
"""
Input and output functions.
"""
import os as _os
import errno as _errno
import sys as _sys
import numpy as _np
from petsc4py import PETSc as _PETSc
import fileinput as _fl
def vecToArray(obj):
""" Converts a PETSc vector to a numpy array, available on *all* MPI nodes.
Args:
obj (petsc4py.PETSc.Vec): input vector.
Returns:
numpy.array :
"""
# scatter vector 'obj' to all processes
comm = obj.getComm()
scatter, obj0 = _PETSc.Scatter.toAll(obj)
scatter.scatter(obj, obj0, False, _PETSc.Scatter.Mode.FORWARD)
return _np.asarray(obj0)
# deallocate
comm.barrier()
scatter.destroy()
obj0.destroy()
def vecToArray0(obj):
""" Converts a PETSc vector to a numpy array available on MPI node 0.
Args:
obj (petsc4py.PETSc.Vec): input vector.
Returns:
numpy.array :
"""
# scatter vector 'obj' to process 0
comm = obj.getComm()
rank = comm.getRank()
scatter, obj0 = _PETSc.Scatter.toZero(obj)
scatter.scatter(obj, obj0, False, _PETSc.Scatter.Mode.FORWARD)
if rank == 0: return _np.asarray(obj0)
# deallocate
comm.barrier()
scatter.destroy()
obj0.destroy()
def arrayToVec(vecArray):
""" Converts a (global) array to a PETSc vector over :attr:`petsc4py.PETSc.COMM_WORLD`.
Args:
vecArray (array or numpy.array): input vector.
Returns:
petsc4py.PETSc.Vec() :
"""
vec = _PETSc.Vec().create(comm=_PETSc.COMM_WORLD)
vec.setSizes(len(vecArray))
vec.setUp()
(Istart,Iend) = vec.getOwnershipRange()
return vec.createWithArray(vecArray[Istart:Iend],
comm=_PETSc.COMM_WORLD)
vec.destroy()
def arrayToMat(matArray):
""" Converts a (global) 2D array to a PETSc matrix over :attr:`petsc4py.PETSc.COMM_WORLD`.
Args:
matArray (array or numpy.array): input square array.
:rtype: petsc4py.PETSc.Mat()
.. important::
Requires `SciPy <http://www.scipy.org>`_.
"""
try:
import scipy.sparse as sparse
except:
print '\nERROR: loading matrices from txt files requires Scipy!'
return
matSparse =matArray
mat = _PETSc.Mat().createAIJ(size=matSparse.shape,comm=_PETSc.COMM_WORLD)
(Istart,Iend) = mat.getOwnershipRange()
ai = matSparse.indptr[Istart:Iend+1] - matSparse.indptr[Istart]
aj = matSparse.indices[matSparse.indptr[Istart]:matSparse.indptr[Iend]]
av = matSparse.data[matSparse.indptr[Istart]:matSparse.indptr[Iend]]
mat.setValuesCSR(ai,aj,av)
mat.assemble()
return mat
mat.destroy()
def matToSparse(mat):
""" Converts a PETSc matrix to a (global) sparse matrix.
Args:
mat (petsc4py.PETSc.Mat): input PETSc matrix.
:rtype: scipy.sparse.csr_matrix
.. important::
Requires `SciPy <http://www.scipy.org>`_.
"""
import scipy.sparse as sparse
data = mat.getValuesCSR()
(Istart,Iend) = mat.getOwnershipRange()
columns = mat.getSize()[0]
sparseSubMat = sparse.csr_matrix(data[::-1],shape=(Iend-Istart,columns))
comm = _PETSc.COMM_WORLD
sparseSubMat = comm.tompi4py().allgather(sparseSubMat)
return sparse.vstack(sparseSubMat)
def adjToH(adj,d=[0],amp=[0.]):
""" Creates a 1 particle PETSc-type Hamiltonian matrix from a PETSc adjacency matrix.
Args:
adj (petsc4py.PETSc.Mat): input PETSc-type adjacency matrix.
d (array of ints): an array containing *integers* indicating the nodes
where diagonal defects are to be placed (e.g. ``d=[0,1,4]``).
amp (array of floats): an array containing *floats* indicating the diagonal defect
amplitudes corresponding to each element in ``d`` (e.g. ``amp=[0.5,-1,4.2]``).
Returns:
: 1 particle Hamiltonian matrix
:rtype: petsc4py.PETSc.Mat()
Warning:
* The size of ``a`` and ``d`` must be identical
>>> amp = [0.5,-1.,4.2]
>>> len(d) == len(amp)
True
* Elements of ``d`` can range from :math:`[0,N-1]` where the adjacency matrix is :math:`N\\times N`.
"""
(Istart,Iend) = adj.getOwnershipRange()
diagSum = []
for i in range(Istart,Iend):
diagSum.append(_np.sum(adj.getRow(i)[-1]))
for j,val in enumerate(d):
if i==val: diagSum[i-Istart] += amp[j]
mat = _PETSc.Mat().create(comm=_PETSc.COMM_WORLD)
mat.setSizes(adj.getSize())
mat.setUp()
for i in range(Istart,Iend):
mat.setValue(i,i,diagSum[i-Istart])
mat.assemble()
mat.axpy(-1,adj)
return mat
mat.destroy()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#---------------------- Vec I/O functions ---------------------------
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def exportVec(vec,filename,filetype):
""" Export a PETSc vector to a file.
Args:
vec (petsc4py.PETSc.Vec): input vector.
filename (str): path to desired output file.
filetype (str): the filetype of the exported vector.
* ``'txt'`` - a column vector in text format.
* ``'bin'`` - a PETSc binary vector.
"""
if _os.path.isabs(filename):
outDir = _os.path.dirname(filename)
else:
outDir = './'+_os.path.dirname(filename)
# create output directory if it doesn't exist
try:
_os.mkdir(outDir)
except OSError as exception:
if exception.errno != _errno.EEXIST:
raise
if filetype == 'txt':
# scatter prob to process 0
comm = vec.getComm()
rank = comm.getRank()
scatter, vec0 = _PETSc.Scatter.toZero(vec)
scatter.scatter(vec, vec0, False, _PETSc.Scatter.Mode.FORWARD)
# use process 0 to write to text file
if rank == 0:
array0 = _np.asarray(vec0)
with open(filename,'w') as f:
for i in range(len(array0)):
f.write('{0: .12e}\n'.format(array0[i]))
# deallocate
comm.barrier()
scatter.destroy()
vec0.destroy()
elif filetype == 'bin':
binSave = _PETSc.Viewer().createBinary(filename, 'w')
binSave(vec)
binSave.destroy()
vec.comm.barrier()
def loadVec(filename,filetype):
""" Import a PETSc vector from a file.
Args:
filename (str): path to input file.
filetype (str): the filetype.
* ``'txt'`` - a column vector in text format.
* ``'bin'`` - a PETSc binary vector.
"""
if filetype == 'txt':
try:
vecArray = _np.loadtxt(filename,dtype=_PETSc.ScalarType)
return arrayToVec(vecArray)
except:
print "\nERROR: input state space file " + filename\
+ " does not exist or is in an incorrect format"
_sys.exit()
elif filetype == 'bin':
binLoad = _PETSc.Viewer().createBinary(filename, 'r')
try:
return _PETSc.Vec().load(binLoad)
except:
print "\nERROR: input state space file " + filename\
+ " does not exist or is in an incorrect format"
_sys.exit()
binLoad.destroy()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#---------------------- Mat I/O functions ---------------------------
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def exportMat(mat,filename,filetype,mattype=None):
""" Export a PETSc matrix to a file.
Args:
mat (petsc4py.PETSc.Mat): input matrix.
filename (str): path to desired output file.
filetype (str): the filetype of the exported vector.
* ``'txt'`` - a 2D matrix array in text format.
* ``'bin'`` - a PETSc binary matrix.
mattype (str): (``None``,``'adj'``) - if set to ``adj``, only
integers ``0`` and ``1`` are written. Note
that this only applied in ``txt`` mode.
"""
rank = _PETSc.Comm.Get_rank(_PETSc.COMM_WORLD)
if _os.path.isabs(filename):
outDir = _os.path.dirname(filename)
else:
outDir = './'+_os.path.dirname(filename)
# create output directory if it doesn't exist
try:
_os.mkdir(outDir)
except OSError as exception:
if exception.errno != _errno.EEXIST:
raise
if filetype == 'txt':
txtSave = _PETSc.Viewer().createASCII(filename, 'w',
format=_PETSc.Viewer.Format.ASCII_DENSE, comm=_PETSc.COMM_WORLD)
txtSave(mat)
txtSave.destroy()
if rank == 0:
for line in _fl.FileInput(filename,inplace=1):
if line[2] != 't':
if mattype == 'adj':
line = line.replace(" i","j")
line = line.replace(" -","-")
line = line.replace("+-","-")
line = line.replace("0000e+01+0.00000e+00j","")
line = line.replace(".00000e+00+0.00000e+00j","")
line = line.replace(".","")
line = line.replace(" -","\t-")
line = line.replace(" ","\t")
line = line.replace(" ","")
line = line.replace("\t"," ")
print line,
else:
line = line.replace(" i","j")
line = line.replace(" -","-")
line = line.replace("+-","-")
print line,
elif filetype == 'bin':
binSave = _PETSc.Viewer().createBinary(filename, 'w', comm=_PETSc.COMM_WORLD)
binSave(mat)
binSave.destroy()
mat.comm.barrier()
def loadMat(filename,filetype,delimiter=None):
""" Import a PETSc matrix from a file.
Args:
filename (str): path to input file.
filetype (str): the filetype.
* ``'txt'`` - a 2D matrix array in text format.
* ``'bin'`` - a PETSc matrix vector.
delimiter (str): this is passed to `numpy.genfromtxt\
<http://docs.scipy.org/doc/numpy/reference/generated/numpy.genfromtxt.html>`_
in the case of strange delimiters in an imported ``txt`` file.
"""
if filetype == 'txt':
try:
try:
if delimiter is None:
matArray = _np.genfromtxt(filename,dtype=_PETSc.ScalarType)
else:
matArray = _np.genfromtxt(filename,dtype=_PETSc.ScalarType,delimiter=delimiter)
except:
filefix = []
for line in _fl.FileInput(filename,inplace=0):
if line[2] != 't':
line = line.replace(" i","j")
line = line.replace(" -","-")
line = line.replace("+-","-")
filefix.append(line)
matArray = _np.genfromtxt(filefix,dtype=_PETSc.ScalarType)
return arrayToMat(matArray)
except:
print "\nERROR: input state space file " + filename\
+ " does not exist or is in an incorrect format"
_sys.exit()
elif filetype == 'bin':
binLoad = _PETSc.Viewer().createBinary(filename, 'r')
try:
return _PETSc.Mat().load(binLoad)
except:
print "\nERROR: input state space file " + filename\
+ " does not exist or is in an incorrect format"
_sys.exit()
binLoad.destroy()
def exportVecToMat(vec,filename,filetype):
""" Export a :math:`N^2` element PETSc vector as a :math:`N\\times N` matrix.
This is useful when wanting to view the full statespace of a 2 particle
quantum walk.
Args:
vec (petsc4py.PETSc.Vec): input :math:`N^2` element vector.
filename (str): path to desired output file.
filetype (str): the filetype of the exported vector.
* ``'txt'`` - an :math:`N\\times N` 2D matrix array in text format.
* ``'bin'`` - an :math:`N\\times N` PETSc binary matrix.
"""
rank = _PETSc.Comm.Get_rank(_PETSc.COMM_WORLD)
if _os.path.isabs(filename):
outDir = _os.path.dirname(filename)
else:
outDir = './'+_os.path.dirname(filename)
# create output directory if it doesn't exist
try:
_os.mkdir(outDir)
except OSError as exception:
if exception.errno != _errno.EEXIST:
raise
vecArray = vecToArray(vec)
matArray = vecArray.reshape([_np.sqrt(vecArray.size),_np.sqrt(vecArray.size)])
if filetype == 'txt':
#if rank == 0: _np.savetxt(filename,matArray)
txtSave = _PETSc.Viewer().createASCII(filename, 'w',
format=_PETSc.Viewer.Format.ASCII_DENSE, comm=_PETSc.COMM_WORLD)
txtSave(arrayToMat(matArray))
txtSave.destroy()
if rank == 0:
for line in _fl.FileInput(filename,inplace=1):
if line[2] != 't':
line = line.replace(" i","j")
line = line.replace(" -","-")
line = line.replace("+-","-")
print line,
elif filetype == 'bin':
binSave = _PETSc.Viewer().createBinary(filename, 'w', comm=_PETSc.COMM_WORLD)
binSave(arrayToMat(matArray))
binSave.destroy()
vec.comm.barrier()
def loadMatToVec(filename,filetype):
""" Load a :math:`N\\times N` matrix as a :math:`N^2` element PETSc vector.
This is useful when wanting to import the full statespace of a 2 particle
quantum walk to use for propagation.
Args:
filename (str): path to the input file.
filetype (str): the filetype
* ``'txt'`` - an :math:`N\\times N` 2D matrix array in text format.
* ``'bin'`` - **Not yet implemented! Please use a txt \
format for this type of import**.
"""
if filetype == 'txt':
try:
try:
matArray = _np.loadtxt(filename,dtype=_PETSc.ScalarType)
except:
filefix = []
for line in _fl.FileInput(filename,inplace=0):
if line[2] != 't':
line = line.replace(" i","j")
line = line.replace(" -","-")
line = line.replace("+-","-")
filefix.append(line)
matArray = _np.loadtxt(filefix,dtype=_PETSc.ScalarType)
vecArray = matArray.reshape(matArray.shape[0]**2)
return arrayToVec(vecArray)
except:
print "\nERROR: input state space file " + filename\
+ " does not exist or is in an incorrect format"
_sys.exit()
elif filetype == 'bin':
print '\nERROR: only works for txt storage!'
_sys.exit()
File diff suppressed because one or more lines are too long
-11
View File
@@ -1,11 +0,0 @@
# Check project status
gcutil getproject --project=<ProjectName> --cache_flag_values
# Start an instance
gcutil addinstance <instanceName>
# Log in
gcutil ssh <instanceName>
# Shut down
gcutil deleteinstance <instanceName>
-145
View File
@@ -1,145 +0,0 @@
#! /bin/bash
locale-gen en_US en_US.UTF-8 hu_HU hu_HU.UTF-8 > output.t
dpkg-reconfigure locales >> output.t
sudo apt-get update >> output.t
echo " "
echo " "
echo " ============================================"
echo " | Installing packages form package manager |"
echo " ============================================"
echo " "
echo " "
sudo apt-get -y install aptitude >> output.t
packages=(gcc gfortran git libopenmpi-dev python-pip python-dev git flex bison cmake vim cython ipython python-scipy python-numpy python-nose python-pip python-matplotlib python-vtk python-h5py libmumps-ptscotch-4.10.0 libmumps-ptscotch-dev libblas-dev liblapack-dev )
for item in ${packages[*]}
do
printf " %-30s\n" $item
done
for item in ${packages[*]}
do
tput cuu1
done
for item in ${packages[*]}
do
sudo aptitude -y install $item >> output.t
printf " %-30s %-4s\n" $item done
done
echo " "
echo " "
echo " ====================================="
echo " | Installing extra Python libraries |"
echo " ====================================="
echo " "
echo " "
pipPackages=(mpi4py pymumps)
for item in ${pipPackages[*]}
do
printf " %-30s\n" $item
done
for item in ${pipPackages[*]}
do
tput cuu1
done
for item in ${pipPackages[*]}
do
sudo pip install $item >> output.t
printf " %-30s %-4s\n" $item done
done
Upgrade=(scipy numpy ipython)
for item in ${Upgrade[*]}
do
printf " %-8s%-7s\n" $item upgrade
done
for item in ${Upgrade[*]}
do
tput cuu1
done
for item in ${Upgrade[*]}
do
sudo pip install $item --upgrade >> output.t
printf " %-8s%-7s %-4s\n" $item upgrade done
done
echo " "
echo " "
echo " ====================="
echo " | Installing SimPEG |"
echo " ====================="
echo " "
echo " "
cd ~
git clone https://github.com/simpeg/simpeg.git >> output.t
cd simpeg/SimPEG/
python setup.py >> output.t
cd ~
mkdir petsc
cd petsc
echo " "
echo " "
echo " ===================="
echo " | Installing PETSc |"
echo " ===================="
echo " "
echo " "
wget http://ftp.mcs.anl.gov/pub/petsc/release-snapshots/petsc-3.4.3.tar.gz
tar -zxf petsc-3.4.3.tar.gz
cd petsc-3.4.3
./configure --with-debugging=no --dowload-mpich=yes --download-blacs=yes --download-f-blas-lapack=yes --download-scalapack=yes --download-mumps=yes --download-ml=yes --download-spooles=yes --download-hypre=yes --dowload-trilinos=yes --download-metis=yes --download-parmetis=yes --download-umfpack=yes --download-ptscotch=yes --download-superlu=yes --download-superlu_dist=yes --download-essl=yes --download-eucild=yes --download-spai=yes --download-mpi4py=yes --download-petsc4py=yes --download-scientificpython=yes
echo "export PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3" >> ~/.bashrc
echo "export PETSC_ARCH=arch-linux2-c-opt" >> ~/.bashrc
export PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3
export PETSC_ARCH=arch-linux2-c-opt
. ~/.bashrc
make PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3 PETSC_ARCH=arch-linux2-c-opt all
make PETSC_DIR=/home/${USER}/petsc/petsc-3.4.3 PETSC_ARCH=arch-linux2-c-opt test
cd ~/petsc
echo " "
echo " "
echo " ======================="
echo " | Installing PETSc4PY |"
echo " ======================="
echo " "
echo " "
git clone https://bitbucket.org/petsc/petsc4py.git
cd petsc4py/
python setup.py build >> output.t
python setup.py install --prefix=~/petsc >> output.t
echo "export PYTHONPATH=~/petsc/lib/python2.7/site-packages:/home/$USER/simpeg:${PYTHONPATH}" >> ~/.bashrc
cd ~
source ~/.bashrc
-22
View File
@@ -1,22 +0,0 @@
#! /bin/bash
sudo aptitude -y update
sudo aptitude -y upgrade
sudo aptitude -y install gcc gfortran git libopenmpi-dev python-pip python-dev
sudo aptitude -y install ipython python-scipy python-numpy python-nose python-pip python-matplotlib
sudo aptitude -y install libmumps-ptscotch-4.10.0 libmumps-ptscotch-dev
sudo aptitude -y install libblas-dev liblapack-dev
sudo pip install mpi4py
sudo pip install pymumps
sudo pip install scipy --upgrade
sudo pip install numpy --upgrade
sudo pip install ipython --upgrade
git clone https://github.com/simpeg/simpeg.git
cd simpeg/SimPEG/
python setup.py
cd ~
echo export PYTHONPATH=/home/$USER/simpeg/ >> .bashrc
source .bashrc
+1 -1
View File
@@ -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
-36
View File
@@ -1,36 +0,0 @@
- Electromagnetics (`simpegEM <http://simpegem.rtfd.org/>`_)
.. 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 <http://simpegpf.rtfd.org/>`_)
.. 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 <http://simpegflow.rtfd.org/>`_)
.. 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 <http://simpeg-dc.rtfd.org/>`_)
.. 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 <http://simpegem1d.rtfd.org/>`_)
.. 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 <http://simpegmt.rtfd.org/>`_)
.. 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
+2 -2
View File
@@ -2,7 +2,6 @@ from __future__ import division
import numpy as np
from scipy.constants import mu_0, pi
from scipy.special import erf
import matplotlib.pyplot as plt
from SimPEG import Utils
@@ -59,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'))
-1
View File
@@ -1 +0,0 @@
import CylInversion
@@ -1,9 +1,16 @@
from SimPEG import *
import SimPEG.EM as EM
from scipy.constants import mu_0
import matplotlib.pyplot as plt
def run(plotIt=True):
"""
EM: FDEM: 1D: Inversion
=======================
Here we will create and run a FDEM 1D inversion.
"""
cs, ncx, ncz, npad = 5., 25, 15, 15
hx = [(cs,ncx), (cs,npad,1.3)]
@@ -24,6 +31,7 @@ def run(plotIt=True):
if plotIt:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1, figsize = (3, 6))
plt.semilogx(sigma[active], mesh.vectorCCz[active])
ax.set_ylim(-600, 0)
@@ -53,6 +61,7 @@ def run(plotIt=True):
survey.Wd = 1/(abs(survey.dobs)*std)
if plotIt:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1, figsize = (10, 6))
ax.loglog(rx.times, dtrue, 'b.-')
ax.loglog(rx.times, survey.dobs, 'r.-')
@@ -81,6 +90,7 @@ def run(plotIt=True):
mopt = inv.run(m0)
if plotIt:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1, figsize = (3, 6))
plt.semilogx(sigma[active], mesh.vectorCCz[active])
plt.semilogx(np.exp(mopt), mesh.vectorCCz[active])
@@ -1,8 +1,40 @@
from SimPEG import *
from SimPEG.FLOW import Richards
import matplotlib.pyplot as plt
def run(plotIt=True):
"""
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
"""
M = Mesh.TensorMesh([np.ones(40)])
M.setCellGradBC('dirichlet')
params = Richards.Empirical.HaverkampParams().celia1990
@@ -28,6 +60,7 @@ def run(plotIt=True):
Hs_H120= getFields(120.,'head')
if not plotIt:return
import matplotlib.pyplot as plt
plt.figure(figsize=(13,5))
plt.subplot(121)
plt.plot(40-M.gridCC, Hs_M10[-1],'b-')
@@ -47,6 +80,7 @@ def run(plotIt=True):
plt.xlabel('Depth, cm')
plt.ylabel('Pressure Head, cm')
plt.legend(('$\Delta t$ = 10 sec','$\Delta t$ = 30 sec','$\Delta t$ = 120 sec'))
plt.show()
if __name__ == '__main__':
run()
@@ -1,7 +1,4 @@
from SimPEG import Mesh, Utils, np, SolverLU
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.mlab import griddata
## 2D DC forward modeling example with Tensor and Curvilinear Meshes
@@ -12,7 +9,6 @@ def run(plotIt=True):
tM = Mesh.TensorMesh(sz)
# Curvilinear Mesh
rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
# Step2: Direct Current (DC) operator
def DCfun(mesh, pts):
D = mesh.faceDiv
@@ -39,6 +35,11 @@ def run(plotIt=True):
phirM = AinvrM*rhsrM
if not plotIt: return
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.mlab import griddata
#Step4: Making Figure
fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
label = ["(a)", "(b)"]
@@ -69,6 +70,7 @@ def run(plotIt=True):
else:
axes[i].set_ylabel(" ")
axes[i].set_xlabel("x")
plt.show()
if __name__ == '__main__':
@@ -1,29 +1,39 @@
from SimPEG import *
class LinearSurvey(Survey.BaseSurvey):
def projectFields(self, u):
return u
class LinearProblem(Problem.BaseProblem):
"""docstring for LinearProblem"""
def run(N=100, plotIt=True):
"""
Inversion: Linear Problem
=========================
surveyPair = LinearSurvey
Here we go over the basics of creating a linear problem and inversion.
def __init__(self, mesh, G, **kwargs):
Problem.BaseProblem.__init__(self, mesh, **kwargs)
self.G = G
"""
def fields(self, m, u=None):
return self.G.dot(m)
class LinearSurvey(Survey.BaseSurvey):
def projectFields(self, u):
return u
def Jvec(self, m, v, u=None):
return self.G.dot(v)
class LinearProblem(Problem.BaseProblem):
def Jtvec(self, m, v, u=None):
return self.G.T.dot(v)
surveyPair = LinearSurvey
def __init__(self, mesh, G, **kwargs):
Problem.BaseProblem.__init__(self, mesh, **kwargs)
self.G = G
def fields(self, m, u=None):
return self.G.dot(m)
def Jvec(self, m, v, u=None):
return self.G.dot(v)
def Jtvec(self, m, v, u=None):
return self.G.T.dot(v)
def run(N, plotIt=True):
np.random.seed(1)
mesh = Mesh.TensorMesh([N])
nk = 20
@@ -52,7 +62,7 @@ def run(N, plotIt=True):
reg = Regularization.Tikhonov(mesh)
dmis = DataMisfit.l2_DataMisfit(survey)
opt = Optimization.InexactGaussNewton(maxIter=20)
opt = Optimization.InexactGaussNewton(maxIter=35)
invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
beta = Directives.BetaSchedule()
betaest = Directives.BetaEstimate_ByEig()
@@ -63,16 +73,18 @@ def run(N, plotIt=True):
if plotIt:
import matplotlib.pyplot as plt
plt.figure(1)
for i in range(prob.G.shape[0]):
plt.plot(prob.G[i,:])
plt.figure(2)
plt.plot(M.vectorCCx, survey.mtrue, 'b-')
plt.plot(M.vectorCCx, mrec, 'r-')
fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
for i in range(prob.G.shape[0]):
axes[0].plot(prob.G[i,:])
axes[0].set_title('Columns of matrix G')
axes[1].plot(M.vectorCCx, survey.mtrue, 'b-')
axes[1].plot(M.vectorCCx, mrec, 'r-')
axes[1].legend(('True Model', 'Recovered Model'))
plt.show()
return prob, survey, mesh, mrec
if __name__ == '__main__':
run(100)
run()
+46
View File
@@ -0,0 +1,46 @@
from SimPEG import *
def run(plotIt=True):
"""
Mesh: Basic: PlotImage
======================
You can use M.PlotImage to plot images on all of the Meshes.
"""
M = Mesh.TensorMesh([32,32])
v = Utils.ModelBuilder.randomModel(M.vnC, seed=789)
v = Utils.mkvc(v)
O = Mesh.TreeMesh([32,32])
O.refine(1)
def function(cell):
if (cell.center[0] < 0.75 and cell.center[0] > 0.25 and
cell.center[1] < 0.75 and cell.center[1] > 0.25):return 5
if (cell.center[0] < 0.9 and cell.center[0] > 0.1 and
cell.center[1] < 0.9 and cell.center[1] > 0.1):return 4
return 3
O.refine(function)
P = M.getInterpolationMat(O.gridCC, 'CC')
ov = P * v
if plotIt:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1,2,figsize=(10,5))
out = M.plotImage(v, grid=True, ax=axes[0])
cb = plt.colorbar(out[0], ax=axes[0]); cb.set_label("Random Field")
axes[0].set_title('TensorMesh')
out = O.plotImage(ov, grid=True, ax=axes[1], clim=[0,1])
cb = plt.colorbar(out[0], ax=axes[1]); cb.set_label("Random Field")
axes[1].set_title('TreeMesh')
plt.show()
if __name__ == '__main__':
run()
+30
View File
@@ -0,0 +1,30 @@
from SimPEG import *
def run(plotIt=True):
"""
Mesh: Basic: Types
==================
Here we show SimPEG used to create three different types of meshes.
"""
sz = [16,16]
tM = Mesh.TensorMesh(sz)
qM = Mesh.TreeMesh(sz)
qM.refine(lambda cell: 4 if np.sqrt(((np.r_[cell.center]-0.5)**2).sum()) < 0.4 else 3)
rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
if plotIt:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1,3,figsize=(14,5))
opts = {}
tM.plotGrid(ax=axes[0], **opts)
axes[0].set_title('TensorMesh')
qM.plotGrid(ax=axes[1], **opts)
axes[1].set_title('TreeMesh')
rM.plotGrid(ax=axes[2], **opts)
axes[2].set_title('CurvilinearMesh')
plt.show()
if __name__ == '__main__':
run()
@@ -0,0 +1,105 @@
from SimPEG import *
def run(plotIt=True, n=60):
"""
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
"""
np.random.seed(5)
# Here we are going to rearrange the equations:
# (phi_ - phi)/dt = A*(d2fdphi2*(phi_ - phi) + dfdphi - L*phi_)
# (phi_ - phi)/dt = A*(d2fdphi2*phi_ - d2fdphi2*phi + dfdphi - L*phi_)
# (phi_ - phi)/dt = A*d2fdphi2*phi_ + A*( - d2fdphi2*phi + dfdphi - L*phi_)
# phi_ - phi = dt*A*d2fdphi2*phi_ + dt*A*(- d2fdphi2*phi + dfdphi - L*phi_)
# phi_ - dt*A*d2fdphi2 * phi_ = dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
# (I - dt*A*d2fdphi2) * phi_ = dt*A*(- d2fdphi2*phi + dfdphi - L*phi_) + phi
# (I - dt*A*d2fdphi2) * phi_ = dt*A*dfdphi - dt*A*d2fdphi2*phi - dt*A*L*phi_ + phi
# (dt*A*d2fdphi2 - I) * phi_ = dt*A*d2fdphi2*phi + dt*A*L*phi_ - phi - dt*A*dfdphi
# (dt*A*d2fdphi2 - I - dt*A*L) * phi_ = (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi
h = [(0.25,n)]
M = Mesh.TensorMesh([h,h])
# Constants
D = a = epsilon = 1.
I = Utils.speye(M.nC)
# Operators
A = D * M.faceDiv * M.cellGrad
L = epsilon**2 * M.faceDiv * M.cellGrad
duration = 75
elapsed = 0.
dexp = -5
phi = np.random.normal(loc=0.5,scale=0.01,size=M.nC)
ii, jj = 0, 0
PHIS = []
capture = np.logspace(-1,np.log10(duration),8)
while elapsed < duration:
dt = min(100, np.exp(dexp))
elapsed += dt
dexp += 0.05
dfdphi = a**2 * 2 * phi * (1 - phi) * (1 - 2 * phi)
d2fdphi2 = Utils.sdiag(a**2 * 2 * (1 - 6 * phi * (1 - phi)))
MAT = (dt*A*d2fdphi2 - I - dt*A*L)
rhs = (dt*A*d2fdphi2 - I)*phi - dt*A*dfdphi
phi = Solver(MAT)*rhs
if elapsed > capture[jj]:
PHIS += [(elapsed, phi.copy())]
jj += 1
if ii % 10 == 0: print ii, elapsed
ii += 1
if plotIt:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2,4,figsize=(14,6))
axes = np.array(axes).flatten().tolist()
for ii, ax in zip(np.linspace(0,len(PHIS)-1,len(axes)),axes):
ii = int(ii)
out = M.plotImage(PHIS[ii][1],ax=ax)
ax.axis('off')
ax.set_title('Elapsed Time: %4.1f'%PHIS[ii][0])
plt.show()
if __name__ == '__main__':
run()
+28
View File
@@ -0,0 +1,28 @@
from SimPEG import *
def run(plotIt=True):
"""
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).
"""
M = Mesh.TreeMesh([32,32])
M.refine(3)
def function(cell):
xyz = cell.center
for i in range(3):
if np.abs(np.sin(xyz[0]*np.pi*2)*0.5 + 0.5 - xyz[1]) < 0.2*i:
return 6-i
return 0
M.refine(function);
if plotIt: M.plotGrid(showIt=True)
if __name__ == '__main__':
run()
+49
View File
@@ -0,0 +1,49 @@
from SimPEG import *
def run(plotIt=True, n=60):
"""
Mesh: QuadTree: FaceDiv
=======================
"""
M = Mesh.TreeMesh([[(1,16)],[(1,16)]], levels=4)
M._refineCell([0,0,0])
M._refineCell([0,0,1])
M._refineCell([4,4,2])
M.__dirty__ = True
M.number()
if plotIt:
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2,1,figsize=(10,10))
M.plotGrid(cells=True, nodes=False, ax=axes[0])
axes[0].axis('off')
axes[0].set_title('Simple QuadTree Mesh')
axes[0].set_xlim([-1,17])
axes[0].set_ylim([-1,17])
for ii, loc in zip(range(M.nC),M.gridCC):
axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='r')
axes[0].plot(M.gridFx[:,0],M.gridFx[:,1], 'g>')
for ii, loc in zip(range(M.nFx),M.gridFx):
axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='g')
axes[0].plot(M.gridFy[:,0],M.gridFy[:,1], 'm^')
for ii, loc in zip(range(M.nFy),M.gridFy):
axes[0].text(loc[0]+0.2,loc[1]+0.2,'%d'%(ii+M.nFx), color='m')
axes[1].spy(M.faceDiv)
axes[1].set_title('Face Divergence')
axes[1].set_ylabel('Cell Number')
axes[1].set_xlabel('Face Number')
plt.show()
if __name__ == '__main__':
run()
@@ -0,0 +1,32 @@
from SimPEG import *
def run(plotIt=True):
"""
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).
"""
M = Mesh.TreeMesh([8,8])
def function(cell):
xyz = cell.center
dist = ((xyz - [0.25,0.25])**2).sum()**0.5
if dist < 0.25:
return 3
return 2
M.refine(function);
M.number()
if plotIt:
import matplotlib.pyplot as plt
M.plotGrid(nodes=True, cells=True, facesX=True)
plt.legend(('Grid', 'Cell Centers', 'Nodes', 'Hanging Nodes', 'X faces', 'Hanging X faces'))
plt.show()
if __name__ == '__main__':
run()
+35
View File
@@ -0,0 +1,35 @@
from SimPEG import *
def run(plotIt=True):
"""
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.
"""
h1 = [(10, 5, -1.3), (5, 20), (10, 3, 1.3)]
M = Mesh.TensorMesh([h1, h1], x0='CN')
if plotIt:
M.plotGrid(showIt=True)
if __name__ == '__main__':
run()
+103 -1
View File
@@ -1 +1,103 @@
import Linear, DCfwd
# Run this file to add imports.
##### AUTOIMPORTS #####
import EM_FDEM_1D_Inversion
import FLOW_Richards_1D_Celia1990
import Forward_BasicDirectCurrent
import Inversion_Linear
import Mesh_Basic_PlotImage
import Mesh_Basic_Types
import Mesh_Operators_CahnHilliard
import Mesh_QuadTree_Creation
import Mesh_QuadTree_FaceDiv
import Mesh_QuadTree_HangingNodes
import Mesh_Tensor_Creation
__examples__ = ["EM_FDEM_1D_Inversion", "FLOW_Richards_1D_Celia1990", "Forward_BasicDirectCurrent", "Inversion_Linear", "Mesh_Basic_PlotImage", "Mesh_Basic_Types", "Mesh_Operators_CahnHilliard", "Mesh_QuadTree_Creation", "Mesh_QuadTree_FaceDiv", "Mesh_QuadTree_HangingNodes", "Mesh_Tensor_Creation"]
##### AUTOIMPORTS #####
if __name__ == '__main__':
"""
Run the following to create the examples documentation and add to the imports at the top.
"""
import shutil, os
from SimPEG import Examples
# Create the examples dir in the docs folder.
docExamplesDir = os.path.sep.join(os.path.realpath(__file__).split(os.path.sep)[:-3] + ['docs', 'examples'])
shutil.rmtree(docExamplesDir)
os.makedirs(docExamplesDir)
# Get all the python examples in this folder
thispath = os.path.sep.join(__file__.split(os.path.sep)[:-1])
exfiles = [f[:-3] for f in os.listdir(thispath) if os.path.isfile(os.path.join(thispath, f)) and f.endswith('.py') and not f.startswith('_')]
# Add the imports to the top in the AUTOIMPORTS section
f = file(__file__, 'r')
inimports = False
out = ''
for line in f:
if not inimports:
out += line
if line == "##### AUTOIMPORTS #####\n":
inimports = not inimports
if inimports:
out += '\n'.join(["import %s"%_ for _ in exfiles])
out += '\n\n__examples__ = ["' + '", "'.join(exfiles)+ '"]\n'
out += '\n##### AUTOIMPORTS #####\n'
f.close()
f = file(__file__, 'w')
f.write(out)
f.close()
def _makeExample(filePath, runFunction):
"""Makes the example given a path of the file and the run function."""
filePath = os.path.realpath(filePath)
name = filePath.split(os.path.sep)[-1].rstrip('.pyc').rstrip('.py')
docstr = runFunction.__doc__
if docstr is None:
doc = '%s\n%s'%(name.replace('_',' '),'='*len(name))
else:
doc = '\n'.join([_[8:].rstrip() for _ in docstr.split('\n')])
out = """.. _examples_%s:
.. --------------------------------- ..
.. ..
.. THIS FILE IS AUTO GENEREATED ..
.. ..
.. SimPEG/Examples/__init__.py ..
.. ..
.. --------------------------------- ..
%s
.. plot::
from SimPEG import Examples
Examples.%s.run()
.. literalinclude:: ../../SimPEG/Examples/%s.py
:language: python
:linenos:
"""%(name,doc,name,name)
rst = os.path.sep.join((filePath.split(os.path.sep)[:-3] + ['docs', 'examples', name + '.rst']))
print 'Creating: %s.rst'%name
f = open(rst, 'w')
f.write(out)
f.close()
for ex in dir(Examples):
if ex.startswith('_'): continue
E = getattr(Examples,ex)
_makeExample(E.__file__, E.run)
-1
View File
@@ -1 +0,0 @@
import Celia1990
+69 -25
View File
@@ -90,13 +90,14 @@
#
from SimPEG import np, sp, Utils, Solver
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
import TreeUtils
try:
import TreeUtils
_IMPORT_TREEUTILS = True
except Exception, e:
_IMPORT_TREEUTILS = False
from InnerProducts import InnerProducts
from TensorMesh import TensorMesh, BaseTensorMesh
import time
@@ -108,6 +109,8 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
_meshType = 'TREE'
def __init__(self, h, x0=None, levels=None):
if not _IMPORT_TREEUTILS:
raise Exception('Could not import the Cython code to run the TreeMesh Try:.\n\npython setup.py build_ext --inplace')
assert type(h) is list, 'h must be a list'
assert len(h) in [2,3], "There is only support for TreeMesh in 2D or 3D."
@@ -1960,11 +1963,18 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
def plotGrid(self, ax=None, showIt=False,
grid=True,
cells=True, cellLine=False,
cells=False, cellLine=False,
nodes=False,
facesX=False, facesY=False, facesZ=False,
edgesX=False, edgesY=False, edgesZ=False):
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
# self.number()
axOpts = {'projection':'3d'} if self.dim == 3 else {}
@@ -1975,24 +1985,28 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
fig = ax.figure
if grid:
X, Y, Z = [], [], []
for ind in self._sortedCells:
p = self._asPointer(ind)
n = self._cellN(p)
h = self._cellH(p)
x = [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0]]
y = [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1]]
if self.dim == 2:
ax.plot(x,y, 'b-')
X += [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0], np.nan]
Y += [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1], np.nan]
elif self.dim == 3:
ax.plot(x,y, 'b-', zs=[n[2]]*5)
z = [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2]]
ax.plot(x,y, 'b-', zs=z)
X += [n[0] , n[0] + h[0], n[0] + h[0], n[0] , n[0], np.nan]*2
Y += [n[1] , n[1] , n[1] + h[1], n[1] + h[1], n[1], np.nan]*2
Z += [n[2]]*5+[np.nan]
Z += [n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], n[2] + h[2], np.nan]
sides = [0,0], [h[0],0], [0,h[1]], [h[0],h[1]]
for s in sides:
x = [n[0] + s[0], n[0] + s[0]]
y = [n[1] + s[1], n[1] + s[1]]
z = [n[2] , n[2] + h[2]]
ax.plot(x,y, 'b-', zs=z)
X += [n[0] + s[0], n[0] + s[0]]
Y += [n[1] + s[1], n[1] + s[1]]
Z += [n[2] , n[2] + h[2]]
if self.dim == 2:
ax.plot(X,Y, 'b-')
elif self.dim == 3:
ax.plot(X,Y, 'b-', zs=Z)
if self.dim == 2:
if cells:
@@ -2004,11 +2018,13 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
ax.plot(self._gridN[:,0], self._gridN[:,1], 'ms')
ax.plot(self._gridN[self._hangingN.keys(),0], self._gridN[self._hangingN.keys(),1], 'ms', ms=10, mfc='none', mec='m')
if facesX:
ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g')
ax.plot(self._gridFx[:,0], self._gridFx[:,1], 'g>')
ax.plot(self._gridFx[self._hangingFx.keys(),0], self._gridFx[self._hangingFx.keys(),1], 'gs', ms=10, mfc='none', mec='g')
if facesY:
ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g')
ax.plot(self._gridFy[:,0], self._gridFy[:,1], 'g^')
ax.plot(self._gridFy[self._hangingFy.keys(),0], self._gridFy[self._hangingFy.keys(),1], 'gs', ms=10, mfc='none', mec='g')
ax.set_xlabel('x1')
ax.set_ylabel('x2')
elif self.dim == 3:
if cells:
ax.plot(self.gridCC[:,0], self.gridCC[:,1], 'r.', zs=self.gridCC[:,2])
@@ -2056,7 +2072,6 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
ind = [key, hf[0]]
ax.plot(self._gridEx[ind,0], self._gridEx[ind,1], 'k:', zs=self._gridEx[ind,2])
if edgesY:
ax.plot(self._gridEy[:,0], self._gridEy[:,1], 'k<', zs=self._gridEy[:,2])
ax.plot(self._gridEy[self._hangingEy.keys(),0], self._gridEy[self._hangingEy.keys(),1], 'ks', ms=10, mfc='none', mec='k', zs=self._gridEy[self._hangingEy.keys(),2])
@@ -2072,15 +2087,28 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
for hf in self._hangingEz[key]:
ind = [key, hf[0]]
ax.plot(self._gridEz[ind,0], self._gridEz[ind,1], 'k:', zs=self._gridEz[ind,2])
ax.set_xlabel('x1')
ax.set_ylabel('x2')
ax.set_zlabel('x3')
ax.grid(True)
if showIt:plt.show()
def plotImage(self, I, ax=None, showIt=True, grid=False):
def plotImage(self, I, ax=None, showIt=False, grid=False, clim=None):
if self.dim == 3: raise Exception('Use plot slice?')
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
if ax is None: ax = plt.subplot(111)
jet = cm = plt.get_cmap('jet')
cNorm = colors.Normalize(vmin=I.min(), vmax=I.max())
cNorm = colors.Normalize(
vmin=I.min() if clim is None else clim[0],
vmax=I.max() if clim is None else clim[1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
ax.set_xlim((self.x0[0], self.h[0].sum()))
ax.set_ylim((self.x0[1], self.h[1].sum()))
@@ -2089,8 +2117,10 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
ax.add_patch(plt.Rectangle((x0[0], x0[1]), sz[0], sz[1], facecolor=scalarMap.to_rgba(I[ii]), edgecolor='k' if grid else 'none'))
# if text: ax.text(self.center[0],self.center[1],self.num)
scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots
plt.colorbar(scalarMap)
ax.set_xlabel('x')
ax.set_ylabel('y')
if showIt: plt.show()
return [scalarMap]
def plotSlice(self, v, vType='CC',
normal='Z', ind=None, grid=True, view='real',
@@ -2102,6 +2132,13 @@ class TreeMesh(BaseTensorMesh, InnerProducts):
assert vType in ['CC','F','E']
assert self.dim == 3
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
szSliceDim = len(getattr(self, 'h'+normal.lower())) #: Size of the sliced dimension
if ind is None: ind = int(szSliceDim/2)
assert type(ind) in [int, long], 'ind must be an integer'
@@ -2191,7 +2228,7 @@ class Cell(object):
@property
def center(self):
if getattr(self, '_center', None) is None:
self._center = self.mesh._cellC(self._pointer)
self._center = np.array(self.mesh._cellC(self._pointer))
return self._center
@property
def h(self): return self.mesh._cellH(self._pointer)
@@ -2248,6 +2285,13 @@ class CellLookUpException(TreeException):
if __name__ == '__main__':
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
def topo(x):
return np.sin(x*(2.*np.pi))*0.3 + 0.5
+7 -61
View File
@@ -1,8 +1,11 @@
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
from SimPEG.Utils import mkvc, animate
from SimPEG.Utils import mkvc
try:
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
except ImportError, e:
print 'Trouble importing matplotlib.'
class TensorView(object):
@@ -479,63 +482,6 @@ class TensorView(object):
ax.grid(True)
if showIt: plt.show()
def slicer(mesh, var, imageType='CC', normal='z', index=0, ax=None, clim=None):
assert normal in 'xyz', 'normal must be x, y, or z'
if ax is None: ax = plt.subplot(111)
I = mesh.r(var,'CC','CC','M')
axes = [p for p in 'xyz' if p not in normal.lower()]
if normal is 'x': I = I[index,:,:]
if normal is 'y': I = I[:,index,:]
if normal is 'z': I = I[:,:,index]
if clim is None: clim = [I.min(),I.max()]
p = ax.pcolormesh(getattr(mesh,'vectorN'+axes[0]),getattr(mesh,'vectorN'+axes[1]),I.T,vmin=clim[0],vmax=clim[1])
ax.axis('tight')
ax.set_xlabel(axes[0])
ax.set_ylabel(axes[1])
return p
def videoSlicer(mesh,var,imageType='CC',normal='z',figsize=(10,8)):
assert mesh.dim > 2, 'This is for 3D meshes only.'
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure(figsize=figsize)
ax = plt.axes()
clim = [var.min(),var.max()]
plt.colorbar(mesh.slicer(var, imageType=imageType, normal=normal, index=0, ax=ax, clim=clim))
tlt = plt.title(normal)
def animateFrame(i):
mesh.slicer(var, imageType=imageType, normal=normal, index=i, ax=ax, clim=clim)
tlt.set_text(normal.upper()+('-Slice: %d, %4.4f' % (i,getattr(mesh,'vectorCC'+normal)[i])))
return animate(fig, animateFrame, frames=mesh.vnC['xyz'.index(normal)])
def video(mesh, var, function, figsize=(10, 8), colorbar=True, skip=1):
"""
Call a function for a list of models to create a video.
::
def function(var, ax, clim, tlt, i):
tlt.set_text('%d'%i)
return mesh.plotImage(var, imageType='CC', ax=ax, clim=clim)
mesh.video([model1, model2, ..., modeln],function)
"""
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure(figsize=figsize)
ax = plt.axes()
VAR = np.concatenate(var)
clim = [VAR.min(),VAR.max()]
tlt = plt.title('')
if colorbar:
plt.colorbar(function(var[0],ax,clim,tlt,0))
frames = np.arange(0,len(var),skip)
def animateFrame(j):
i = frames[j]
function(var[i],ax,clim,tlt,i)
return animate(fig, animateFrame, frames=len(frames))
class CylView(object):
+3 -82
View File
@@ -24,7 +24,7 @@ class BaseRegularization(object):
Utils.setKwargs(self, **kwargs)
self.mesh = mesh
assert isinstance(mesh, Mesh.BaseMesh), "mesh must be a SimPEG.Mesh object."
self.mapping = mapping or Maps.IdentityMap(mesh)
self.mapping = mapping or self.mapPair(mesh)
self.mapping._assertMatchesPair(self.mapPair)
@property
@@ -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 )
+1 -1
View File
@@ -1,5 +1,4 @@
import numpy as np
import matplotlib.pyplot as plt
from numpy.linalg import norm
from SimPEG.Utils import mkvc, sdiag, diagEst
from SimPEG import Utils
@@ -311,6 +310,7 @@ def checkDerivative(fctn, x0, num=7, plotIt=True, dx=None, expectedOrder=2, tole
if plotIt:
import matplotlib.pyplot as plt
ax = ax or plt.subplot(111)
ax.loglog(h, E0, 'b')
ax.loglog(h, E1, 'g--')
-1
View File
@@ -3,7 +3,6 @@ from codeutils import *
from meshutils import exampleLrmGrid, meshTensor, closestPoints, readUBCTensorMesh, writeUBCTensorMesh, writeUBCTensorModel, readVTRFile, writeVTRFile
from curvutils import volTetra, faceInfo, indexCube
from interputils import interpmat
from ipythonutils import easyAnimate as animate
from CounterUtils import *
import ModelBuilder
import SolverUtils
-28
View File
@@ -1,28 +0,0 @@
from tempfile import NamedTemporaryFile
import matplotlib.pyplot as plt
from matplotlib import animation
# http://jakevdp.github.io/blog/2013/05/12/embedding-matplotlib-animations/
# http://www.renevolution.com/how-to-install-ffmpeg-on-mac-os-x/
VIDEO_TAG = """<video controls loop>
<source src="data:video/x-m4v;base64,{0}" type="video/mp4">
Your browser does not support the video tag.
</video>"""
def anim_to_html(anim):
if not hasattr(anim, '_encoded_video'):
with NamedTemporaryFile(suffix='.mp4') as f:
anim.save(f.name, fps=20, extra_args=['-vcodec', 'libx264', '-pix_fmt', 'yuv420p'])
video = open(f.name, "rb").read()
anim._encoded_video = video.encode("base64")
return VIDEO_TAG.format(anim._encoded_video)
def display_animation(anim):
plt.close(anim._fig)
return anim_to_html(anim)
animation.Animation._repr_html_ = display_animation
easyAnimate = animation.FuncAnimation
+1 -1
View File
@@ -15,7 +15,7 @@ import Directives
import Inversion
import Tests
__version__ = '0.1.3'
__version__ = '0.1.9'
__author__ = 'Rowan Cockett'
__license__ = 'MIT'
__copyright__ = 'Copyright 2014 Rowan Cockett'
Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

+9 -2
View File
@@ -3,8 +3,15 @@
Examples
********
Forward problem
===============
.. 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>`_
+19
View File
@@ -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 <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
+1 -6
View File
@@ -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:
@@ -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:
+11
View File
@@ -0,0 +1,11 @@
Inversion Components
********************
.. toctree::
:maxdepth: 3
api_DataMisfit
api_Regularization
api_Optimization
api_Inversion
+2 -17
View File
@@ -23,23 +23,8 @@ the implementations.
.. plot::
from SimPEG import Mesh, Utils, np
import matplotlib.pyplot as plt
sz = [10,10]
tM = Mesh.TensorMesh(sz)
qM = Mesh.TreeMesh(sz)
qM.refine(lambda X: 1 if np.sqrt(((X-0.5)**2).sum()) < 0.3 else 0)
rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
fig, axes = plt.subplots(1,3,figsize=(14,5))
opts = {}
tM.plotGrid(ax=axes[0], **opts)
axes[0].set_title('TensorMesh')
qM.plotGrid(ax=axes[1], **opts)
axes[1].set_title('TreeMesh')
rM.plotGrid(ax=axes[2], **opts)
axes[2].set_title('CurvilinearMesh')
plt.show()
from SimPEG import Examples
Examples.Mesh_Basic_Types.run()
Variable Locations and Terminology
+10 -10
View File
@@ -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:
+9
View File
@@ -0,0 +1,9 @@
Optimize
********
.. automodule:: SimPEG.Optimization
:show-inheritance:
:private-members:
:members:
:undoc-members:
+100
View File
@@ -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:
+1 -1
View File
@@ -3,6 +3,6 @@
Testing SimPEG
==============
.. automodule:: SimPEG.Tests.TestUtils
.. automodule:: SimPEG.Tests
:members:
:undoc-members:
+10
View File
@@ -0,0 +1,10 @@
Utilities
*********
.. toctree::
:maxdepth: 2
api_Solver
api_Maps
api_Utils
api_Tests
+3 -6
View File
@@ -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):
+58 -6
View File
@@ -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
+2 -2
View File
@@ -1,7 +1,7 @@
.. _api_installing:
Installation
************
Getting Started with SimPEG
***************************
Dependencies
============
-17
View File
@@ -1,17 +0,0 @@
.. _api_license:
License
*******
.. include:: ../LICENSE
Authors
*******
.. include:: ../AUTHORS.rst
Projects Using SimPEG
*********************
.. include:: ../PROJECTS.rst
+2 -2
View File
@@ -51,9 +51,9 @@ copyright = u'2013, SimPEG Developers'
# built documents.
#
# The short X.Y version.
version = '0.1.3'
version = '0.1.9'
# The full version, including alpha/beta/rc tags.
release = '0.1.3'
release = '0.1.9'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
+3 -4
View File
@@ -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:
+2 -3
View File
@@ -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
+26
View File
@@ -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,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,21 @@
.. _examples_Forward_BasicDirectCurrent:
.. --------------------------------- ..
.. ..
.. THIS FILE IS AUTO GENEREATED ..
.. ..
.. SimPEG/Examples/__init__.py ..
.. ..
.. --------------------------------- ..
Forward BasicDirectCurrent
==========================
.. plot::
from SimPEG import Examples
Examples.Forward_BasicDirectCurrent.run()
.. literalinclude:: ../../SimPEG/Examples/Forward_BasicDirectCurrent.py
:language: python
:linenos:
+26
View File
@@ -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:
+27
View File
@@ -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:
+26
View File
@@ -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:
+31
View File
@@ -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:
+26
View File
@@ -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:
+43
View File
@@ -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:
+67 -84
View File
@@ -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
+3 -1
View File
@@ -64,6 +64,7 @@ cython_files = [
"SimPEG/Mesh/TreeUtils"
]
extensions = [Extension(f, [f+ext]) for f in cython_files]
scripts = [f+'.pyx' for f in cython_files]
if USE_CYTHON and "cleanall" not in args:
from Cython.Build import cythonize
@@ -76,7 +77,7 @@ with open("README.rst") as f:
setup(
name = "SimPEG",
version = "0.1.3",
version = "0.1.9",
packages = find_packages(),
install_requires = ['numpy>=1.7',
'scipy>=0.13',
@@ -95,5 +96,6 @@ setup(
use_2to3 = False,
include_dirs=[np.get_include()],
ext_modules = extensions,
scripts=scripts,
**cythonKwargs
)
-11
View File
@@ -1,11 +0,0 @@
if __name__ == '__main__':
import os
import glob
import unittest
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
suites = [unittest.defaultTestLoader.loadTestsFromName(str) for str
in module_strings]
testSuite = unittest.TestSuite(suites)
unittest.TextTestRunner(verbosity=2).run(testSuite)
-10
View File
@@ -1,10 +0,0 @@
import unittest, os
from SimPEG.EM import Examples
class EM_ExamplesRunning(unittest.TestCase):
def test_CylInversion(self):
Examples.CylInversion.run(plotIt=False)
if __name__ == '__main__':
unittest.main()
@@ -38,7 +38,7 @@ def derivTest(fdemType, comp):
survey = prb.survey
def fun(x):
return survey.dpred(x), lambda x: prb.Jvec(x0, x)
return Tests.checkDerivative(fun, x0, num=3, plotIt=False, eps=FLR)
return Tests.checkDerivative(fun, x0, num=2, plotIt=False, eps=FLR)
class FDEM_DerivTests(unittest.TestCase):
+11 -8
View File
@@ -1,17 +1,20 @@
import unittest
import sys
from SimPEG.Examples import Linear, DCfwd
from SimPEG import Examples
import numpy as np
class TestLinear(unittest.TestCase):
def test_running(self):
Linear.run(100, plotIt=False)
def get(test):
def test_func(self):
print '\nTesting %s.run(plotIt=False)\n'%test
getattr(Examples, test).run(plotIt=False)
self.assertTrue(True)
return test_func
attrs = dict()
for test in Examples.__examples__:
attrs['test_'+test] = get(test)
TestExamples = type('TestExamples', (unittest.TestCase,), attrs)
class TestDCfwd(unittest.TestCase):
def test_running(self):
DCfwd.run(plotIt=False)
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
-12
View File
@@ -1,12 +0,0 @@
import unittest
import sys
from SimPEG.FLOW.Examples import Celia1990
import numpy as np
class TestCelia1990(unittest.TestCase):
def test_running(self):
Celia1990.run(plotIt=False)
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()