Forward Problem

Problem Class

The problem is a partial differential equation of the form:

\[c(m, u) = 0\]

Here, \(m\) is the model and u is the field (or fields). Given the model, \(m\), we can calculate the fields \(u(m)\), however, the data we collect is a subset of the fields, and can be defined by a linear projection, \(P\).

\[d_\text{pred} = P u(m)\]

For the inverse problem, we are interested in how changing the model transforms the data, as such we can take write the Taylor expansion:

\[Pu(m + hv) = Pu(m) + hP\frac{\partial u(m)}{\partial m} v + \mathcal{O}(h^2 \left\| v \right\| )\]

We can linearize and define the sensitivity matrix as:

\[J = P\frac{\partial u}{\partial m}\]

The sensitivity matrix, and it’s transpose will be used in the inverse problem to (locally) find how model parameters change the data, and optimize!

Working with the general PDE, \(c(m, u) = 0\), where m is the model and u is the field, the sensitivity is defined as:

\[J = P\frac{\partial u}{\partial m}\]

We can take the derivative of the PDE:

\[\nabla_m c(m, u) \partial m + \nabla_u c(m, u) \partial u = 0\]

If the forward problem is invertible, then we can rearrange for \(\frac{\partial u}{\partial m}\):

\[J = - P \left( \nabla_u c(m, u) \right)^{-1} \nabla_m c(m, u)\]

This can often be computed given a vector (i.e. \(J(v)\)) rather than stored, as \(J\) is a large dense matrix.

The API

Problem

class SimPEG.Problem.BaseProblem(mesh, **kwargs)[source]
Problem is the base class for all geophysical forward problems
in SimPEG.

Optional Properties:

  • model (Model): Inversion model., a numpy array of <type ‘float’>, <type ‘int’> with shape (*)
counter = None

A SimPEG.Utils.Counter object

surveyPair

A SimPEG.Survey Class

alias of BaseSurvey

mapPair

A SimPEG.Map Class

alias of IdentityMap

class Solver(A, **kwargs)

A SimPEG Solver class.

clean()
solverOpts = {}

Solver options as a kwarg dict

mesh = None

A discretize instance.

mapping

Setting an unnamed mapping has been depreciated in v0.4.0. Please see the release notes for more details.

curModel

Setting the curModel is depreciated.

Use SimPEG.Problem.model instead.

survey

The survey object for this problem.

pair(d)[source]

Bind a survey to this problem instance using pointers.

unpair()[source]

Unbind a survey from this problem instance.

deleteTheseOnModelUpdate = []

List of strings, e.g. [‘_MeSigma’, ‘_MeSigmaI’]

ispaired

True if the problem is paired to a survey.

Jvec(m, v, f=None)[source]

Effect of J(m) on a vector v.

Parameters:
Return type:

numpy.array

Returns:

Jv

Jtvec(m, v, f=None)[source]

Effect of transpose of J(m) on a vector v.

Parameters:
Return type:

numpy.array

Returns:

JTv

Jvec_approx(m, v, f=None)[source]

Approximate effect of J(m) on a vector v

Parameters:
Return type:

numpy.array

Returns:

approxJv

Jtvec_approx(m, v, f=None)[source]

Approximate effect of transpose of J(m) on a vector v.

Parameters:
Return type:

numpy.array

Returns:

JTv

fields(m)[source]

The field given the model.

Parameters:m (numpy.array) – model
Return type:numpy.array
Returns:u, the fields
class SimPEG.Problem.BaseTimeProblem(mesh, **kwargs)[source]

Sets up that basic needs of a time domain problem.

Optional Properties:

  • model (Model): Inversion model., a numpy array of <type ‘float’>, <type ‘int’> with shape (*)
timeSteps

Sets/gets the timeSteps for the time domain problem.

You can set as an array of dt’s or as a list of tuples/floats. Tuples must be length two with [..., (dt, repeat), ...]

For example, the following setters are the same:

prob.timeSteps = [(1e-6, 3), 1e-5, (1e-4, 2)]
prob.timeSteps = np.r_[1e-6,1e-6,1e-6,1e-5,1e-4,1e-4]
nT

Number of time steps.

t0
times

Modeling times

timeMesh

Fields

class SimPEG.Fields.Fields(mesh, survey, **kwargs)[source]

Fancy Field Storage

u[:,’phi’] = phi print(u[src0,’phi’])

knownFields = None

Known fields, a dict with locations, e.g. {“e”: “E”, “phi”: “CC”}

dtype

dtype is the type of the storage matrix. This can be a dictionary.

alias of float

aliasFields = None

Aliased fields, a dict with [alias, location, function], e.g. {“b”:[“e”,”F”,lambda(F,e,ind)]}

startup()[source]
approxSize

The approximate cost to storing all of the known fields.

class SimPEG.Fields.TimeFields(mesh, survey, **kwargs)[source]

Fancy Field Storage for time domain problems

u[:,’phi’, timeInd] = phi print(u[src0,’phi’])

Survey

class SimPEG.Survey.BaseSurvey(**kwargs)[source]

Survey holds the observed data, and the standard deviations.

std = None

Estimated Standard Deviations

eps = None

Estimated Noise Floor

dobs = None

Observed data

dtrue = None

True data, if data is synthetic

mtrue = None

True model, if data is synthetic

counter = None

A SimPEG.Utils.Counter object

srcPair

Source Pair

alias of BaseSrc

srcList

Source List

getSourceIndex(sources)[source]
prob

The geophysical problem that explains this survey, use:

survey.pair(prob)
mesh

Mesh of the paired problem.

pair(p)[source]

Bind a problem to this survey instance using pointers

unpair()[source]

Unbind a problem from this survey instance

ispaired
nD

Number of data

vnD

Vector number of data

nSrc

Number of Sources

dpred(m, f=None)[source]

Create the projected data from a model. The fields, f, (if provided) will be used for the predicted data instead of recalculating the fields (which may be expensive!).

\[d_\text{pred} = P(f(m))\]

Where P is a projection of the fields onto the data space.

Note

To use survey.dpred(), SimPEG requires that a problem be bound to the survey. If a problem has not been bound, an Exception will be raised. To bind a problem to the Data object:

survey.pair(myProblem)
eval(f)[source]

This function projects the fields onto the data space.

\[d_\text{pred} = \mathbf{P} f(m)\]
evalDeriv(f)[source]

This function s the derivative of projects the fields onto the data space.

\[\frac{\partial d_\text{pred}}{\partial u} = \mathbf{P}\]
residual(m, f=None)[source]
Parameters:
Return type:

numpy.array

Returns:

data residual

The data residual:

\[\mu_\text{data} = \mathbf{d}_\text{pred} - \mathbf{d}_\text{obs}\]
isSynthetic

Check if the data is synthetic.

makeSyntheticData(m, std=0.05, f=None, force=False)[source]

Make synthetic data given a model, and a standard deviation.

Parameters:
  • m (numpy.array) – geophysical model
  • std (numpy.array) – standard deviation
  • u (numpy.array) – fields for the given model (if pre-calculated)
  • force (bool) – force overwriting of dobs
class SimPEG.Survey.BaseSrc(rxList, **kwargs)[source]

SimPEG Source Object

loc = None

Location [x,y,z]

rxPair

alias of BaseRx

rxList = None

SimPEG Receiver List

nD

Number of data

vnD

Vector number of data

class SimPEG.Survey.BaseRx(locs, rxType, **kwargs)[source]

SimPEG Receiver Object

knownRxTypes = None

Set this to a list of strings to ensure that srcType is known

projGLoc = 'CC'

Projection grid location, default is CC

storeProjections = True

Store calls to getP (organized by mesh)

locs = None

Locations (nRx x nDim)

rxType

Receiver Type

nD

Number of data in the receiver.

getP(mesh, projGLoc=None)[source]

Returns the projection matrices as a list for all components collected by the receivers.

Note

Projection matrices are stored as a dictionary listed by meshes.

class SimPEG.Survey.BaseTimeRx(locs, times, rxType, **kwargs)[source]

SimPEG Receiver Object

projTLoc = 'N'
times = None

Times when the receivers were active.

nD

Number of data in the receiver.

getSpatialP(mesh)[source]

Returns the spatial projection matrix.

Note

This is not stored in memory, but is created on demand.

getTimeP(timeMesh)[source]

Returns the time projection matrix.

Note

This is not stored in memory, but is created on demand.

getP(mesh, timeMesh)[source]

Returns the projection matrices as a list for all components collected by the receivers.

Note

Projection matrices are stored as a dictionary (mesh, timeMesh) if storeProjections is True

class SimPEG.Survey.Data(survey, v=None)[source]

Fancy data storage by Src and Rx

tovec()[source]
fromvec(v)[source]