mirror of
https://github.com/wassname/simpeg.git
synced 2026-06-30 17:59:02 +08:00
Merge commit '6d3d8d78b601a11c52e90f87367f7b40e4d537a5' into parallel
This commit is contained in:
+1
-1
@@ -1,4 +1,4 @@
|
||||
[bumpversion]
|
||||
current_version = 0.1.1
|
||||
current_version = 0.1.3
|
||||
files = setup.py SimPEG/__init__.py docs/conf.py
|
||||
|
||||
|
||||
+59
-13
@@ -144,23 +144,69 @@ class BetaSchedule(InversionDirective):
|
||||
if self.debug: print 'BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter
|
||||
self.invProb.beta /= self.coolingFactor
|
||||
|
||||
|
||||
|
||||
class SaveModelEveryIteration(InversionDirective):
|
||||
"""SaveModelEveryIteration"""
|
||||
class TargetMisfit(InversionDirective):
|
||||
|
||||
@property
|
||||
def modelName(self):
|
||||
if getattr(self, '_modelName', None) is None:
|
||||
from datetime import datetime
|
||||
self._modelName = 'inversionModel-%s'%datetime.now().strftime('%Y-%m-%d')
|
||||
return self._modelName
|
||||
@modelName.setter
|
||||
def modelName(self, value):
|
||||
self._modelName = value
|
||||
def target(self):
|
||||
if getattr(self, '_target', None) is None:
|
||||
self._target = self.survey.nD
|
||||
return self._target
|
||||
@target.setter
|
||||
def target(self, val):
|
||||
self._target = val
|
||||
|
||||
def endIter(self):
|
||||
np.save('%03d-%s' % (self.opt.iter, self.modelName), self.opt.xc)
|
||||
if self.invProb.phi_d < self.target:
|
||||
self.opt.stopNextIteration = True
|
||||
|
||||
|
||||
|
||||
class _SaveEveryIteration(InversionDirective):
|
||||
@property
|
||||
def name(self):
|
||||
if getattr(self, '_name', None) is None:
|
||||
self._name = 'InversionModel'
|
||||
return self._name
|
||||
@name.setter
|
||||
def name(self, value):
|
||||
self._name = value
|
||||
|
||||
@property
|
||||
def fileName(self):
|
||||
if getattr(self, '_fileName', None) is None:
|
||||
from datetime import datetime
|
||||
self._fileName = '%s-%s'%(self.name, datetime.now().strftime('%Y-%m-%d-%H-%M'))
|
||||
return self._fileName
|
||||
@fileName.setter
|
||||
def fileName(self, value):
|
||||
self._fileName = value
|
||||
|
||||
|
||||
class SaveModelEveryIteration(_SaveEveryIteration):
|
||||
"""SaveModelEveryIteration"""
|
||||
|
||||
def initialize(self):
|
||||
print "SimPEG.SaveModelEveryIteration will save your models as: '###-%s.npy'"%self.fileName
|
||||
|
||||
def endIter(self):
|
||||
np.save('%03d-%s' % (self.opt.iter, self.fileName), self.opt.xc)
|
||||
|
||||
|
||||
class SaveOutputEveryIteration(_SaveEveryIteration):
|
||||
"""SaveModelEveryIteration"""
|
||||
|
||||
def initialize(self):
|
||||
print "SimPEG.SaveOutputEveryIteration will save your inversion progress as: '###-%s.txt'"%self.fileName
|
||||
f = open(self.fileName+'.txt', 'w')
|
||||
f.write(" # beta phi_d phi_m f\n")
|
||||
f.close()
|
||||
|
||||
def endIter(self):
|
||||
f = open(self.fileName+'.txt', 'a')
|
||||
f.write(' %3d %1.4e %1.4e %1.4e %1.4e\n'%(self.opt.iter, self.invProb.beta, self.invProb.phi_d, self.invProb.phi_m, self.opt.f))
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
|
||||
# class UpdateReferenceModel(Parameter):
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
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
|
||||
|
||||
# Step1: Generate Tensor and Curvilinear Mesh
|
||||
sz = [40,40]
|
||||
# Tensor Mesh
|
||||
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
|
||||
G = D.T
|
||||
sigma = 1e-2*np.ones(mesh.nC)
|
||||
Msigi = mesh.getFaceInnerProduct(1./sigma)
|
||||
MsigI = Utils.sdInv(Msigi)
|
||||
A = D*MsigI*G
|
||||
A[-1,-1] /= mesh.vol[-1] # Remove null space
|
||||
rhs = np.zeros(mesh.nC)
|
||||
txind = Utils.meshutils.closestPoints(mesh, pts)
|
||||
rhs[txind] = np.r_[1,-1]
|
||||
return A, rhs
|
||||
|
||||
pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))
|
||||
|
||||
#Step3: Solve DC problem (LU solver)
|
||||
AtM, rhstM = DCfun(tM, pts)
|
||||
AinvtM = SolverLU(AtM)
|
||||
phitM = AinvtM*rhstM
|
||||
|
||||
ArM, rhsrM = DCfun(rM, pts)
|
||||
AinvrM = SolverLU(ArM)
|
||||
phirM = AinvrM*rhsrM
|
||||
|
||||
#Step4: Making Figure
|
||||
fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
|
||||
label = ["(a)", "(b)"]
|
||||
opts = {}
|
||||
vmin, vmax = phitM.min(), phitM.max()
|
||||
dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)
|
||||
|
||||
#TODO: At the moment Curvilinear Mesh do not have plotimage
|
||||
|
||||
Xi = tM.gridCC[:,0].reshape(sz[0], sz[1], order='F')
|
||||
Yi = tM.gridCC[:,1].reshape(sz[0], sz[1], order='F')
|
||||
PHIrM = griddata(rM.gridCC[:,0], rM.gridCC[:,1], phirM, Xi, Yi, interp='linear')
|
||||
axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax)
|
||||
|
||||
cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)")
|
||||
cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)")
|
||||
|
||||
tM.plotGrid(ax=axes[0], **opts)
|
||||
axes[0].set_title('TensorMesh')
|
||||
rM.plotGrid(ax=axes[1], **opts)
|
||||
axes[1].set_title('CurvilinearMesh')
|
||||
for i in range(2):
|
||||
axes[i].set_xlim(0.025, 0.975)
|
||||
axes[i].set_ylim(0.025, 0.975)
|
||||
axes[i].text(0., 1.0, label[i], fontsize=20)
|
||||
if i==0:
|
||||
axes[i].set_ylabel("y")
|
||||
else:
|
||||
axes[i].set_ylabel(" ")
|
||||
axes[i].set_xlabel("x")
|
||||
|
||||
plt.show()
|
||||
@@ -0,0 +1,261 @@
|
||||
import Utils, numpy as np, scipy.sparse as sp
|
||||
|
||||
class Fields(object):
|
||||
"""Fancy Field Storage
|
||||
|
||||
u[:,'phi'] = phi
|
||||
print u[src0,'phi']
|
||||
|
||||
"""
|
||||
|
||||
knownFields = None #: Known fields, a dict with locations, e.g. {"e": "E", "phi": "CC"}
|
||||
aliasFields = None #: Aliased fields, a dict with [alias, location, function], e.g. {"b":["e","F",lambda(F,e,ind)]}
|
||||
dtype = float #: dtype is the type of the storage matrix. This can be a dictionary.
|
||||
|
||||
def __init__(self, mesh, survey, **kwargs):
|
||||
self.survey = survey
|
||||
self.mesh = mesh
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
self._fields = {}
|
||||
|
||||
if self.knownFields is None:
|
||||
raise Exception('knownFields cannot be set to None')
|
||||
if self.aliasFields is None:
|
||||
self.aliasFields = {}
|
||||
|
||||
allFields = [k for k in self.knownFields] + [a for a in self.aliasFields]
|
||||
assert len(allFields) == len(set(allFields)), 'Aliased fields and Known Fields have overlapping definitions.'
|
||||
self.startup()
|
||||
|
||||
def startup(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def approxSize(self):
|
||||
"""The approximate cost to storing all of the known fields."""
|
||||
sz = 0.0
|
||||
for f in self.knownFields:
|
||||
loc =self.knownFields[f]
|
||||
sz += np.array(self._storageShape(loc)).prod()*8.0/(1024**2)
|
||||
return "%e MB"%sz
|
||||
|
||||
def _storageShape(self, loc):
|
||||
nSrc = self.survey.nSrc
|
||||
|
||||
nP = {'CC': self.mesh.nC,
|
||||
'N': self.mesh.nN,
|
||||
'F': self.mesh.nF,
|
||||
'E': self.mesh.nE}[loc]
|
||||
|
||||
return (nP, nSrc)
|
||||
|
||||
def _initStore(self, name):
|
||||
if name in self._fields:
|
||||
return self._fields[name]
|
||||
|
||||
assert name in self.knownFields, 'field name is not known.'
|
||||
|
||||
loc = self.knownFields[name]
|
||||
|
||||
if type(self.dtype) is dict:
|
||||
dtype = self.dtype[name]
|
||||
else:
|
||||
dtype = self.dtype
|
||||
field = np.zeros(self._storageShape(loc), dtype=dtype)
|
||||
|
||||
self._fields[name] = field
|
||||
|
||||
return field
|
||||
|
||||
def _srcIndex(self, srcTestList):
|
||||
if type(srcTestList) is slice:
|
||||
ind = srcTestList
|
||||
else:
|
||||
ind = self.survey.getSourceIndex(srcTestList)
|
||||
return ind
|
||||
|
||||
def _nameIndex(self, name, accessType):
|
||||
|
||||
if type(name) is slice:
|
||||
assert name == slice(None,None,None), 'Fancy field name slicing is not supported... yet.'
|
||||
name = None
|
||||
|
||||
if name is None:
|
||||
return
|
||||
if accessType=='set' and name not in self.knownFields:
|
||||
if name in self.aliasFields:
|
||||
raise KeyError("Invalid field name (%s) for setter, you can't set an aliased property"%name)
|
||||
else:
|
||||
raise KeyError('Invalid field name (%s) for setter'%name)
|
||||
|
||||
elif accessType=='get' and (name not in self.knownFields and name not in self.aliasFields):
|
||||
raise KeyError('Invalid field name (%s) for getter'%name)
|
||||
return name
|
||||
|
||||
def _indexAndNameFromKey(self, key, accessType):
|
||||
if type(key) is not tuple:
|
||||
key = (key,)
|
||||
if len(key) == 1:
|
||||
key += (None,)
|
||||
|
||||
assert len(key) == 2, 'must be [Src, fieldName]'
|
||||
|
||||
srcTestList, name = key
|
||||
name = self._nameIndex(name, accessType)
|
||||
ind = self._srcIndex(srcTestList)
|
||||
return ind, name
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
ind, name = self._indexAndNameFromKey(key, 'set')
|
||||
if name is None:
|
||||
freq = key
|
||||
assert type(value) is dict, 'New fields must be a dictionary, if field is not specified.'
|
||||
newFields = value
|
||||
elif name in self.knownFields:
|
||||
newFields = {name: value}
|
||||
else:
|
||||
raise Exception('Unknown setter')
|
||||
|
||||
for name in newFields:
|
||||
field = self._initStore(name)
|
||||
self._setField(field, newFields[name], name, ind)
|
||||
|
||||
def __getitem__(self, key):
|
||||
ind, name = self._indexAndNameFromKey(key, 'get')
|
||||
if name is None:
|
||||
out = {}
|
||||
for name in self._fields:
|
||||
out[name] = self._getField(name, ind)
|
||||
return out
|
||||
return self._getField(name, ind)
|
||||
|
||||
def _setField(self, field, val, name, ind):
|
||||
if isinstance(val, np.ndarray) and (field.shape[0] == field.size or val.ndim == 1):
|
||||
val = Utils.mkvc(val,2)
|
||||
field[:,ind] = val
|
||||
|
||||
def _getField(self, name, ind):
|
||||
if name in self._fields:
|
||||
out = self._fields[name][:,ind]
|
||||
else:
|
||||
# Aliased fields
|
||||
alias, loc, func = self.aliasFields[name]
|
||||
|
||||
srcII = np.array(self.survey.srcList)[ind]
|
||||
srcII = srcII.tolist()
|
||||
|
||||
if type(func) is str:
|
||||
assert hasattr(self, func), 'The alias field function is a string, but it does not exist in the Fields class.'
|
||||
func = getattr(self, func)
|
||||
out = func(self._fields[alias][:,ind], srcII)
|
||||
if out.shape[0] == out.size or out.ndim == 1:
|
||||
out = Utils.mkvc(out,2)
|
||||
return out
|
||||
|
||||
def __contains__(self, other):
|
||||
if other in self.aliasFields:
|
||||
other = self.aliasFields[other][0]
|
||||
return self._fields.__contains__(other)
|
||||
|
||||
|
||||
class TimeFields(Fields):
|
||||
"""Fancy Field Storage for time domain problems
|
||||
|
||||
u[:,'phi', timeInd] = phi
|
||||
print u[src0,'phi']
|
||||
|
||||
"""
|
||||
|
||||
def _storageShape(self, loc):
|
||||
nP = {'CC': self.mesh.nC,
|
||||
'N': self.mesh.nN,
|
||||
'F': self.mesh.nF,
|
||||
'E': self.mesh.nE}[loc]
|
||||
nSrc = self.survey.nSrc
|
||||
nT = self.survey.prob.nT + 1
|
||||
return (nP, nSrc, nT)
|
||||
|
||||
def _indexAndNameFromKey(self, key, accessType):
|
||||
if type(key) is not tuple:
|
||||
key = (key,)
|
||||
if len(key) == 1:
|
||||
key += (None,)
|
||||
if len(key) == 2:
|
||||
key += (slice(None,None,None),)
|
||||
|
||||
assert len(key) == 3, 'must be [Src, fieldName, times]'
|
||||
|
||||
srcTestList, name, timeInd = key
|
||||
|
||||
name = self._nameIndex(name, accessType)
|
||||
srcInd = self._srcIndex(srcTestList)
|
||||
|
||||
return (srcInd, timeInd), name
|
||||
|
||||
def _correctShape(self, name, ind, deflate=False):
|
||||
srcInd, timeInd = ind
|
||||
if name in self.knownFields:
|
||||
loc = self.knownFields[name]
|
||||
else:
|
||||
loc = self.aliasFields[name][1]
|
||||
nP, total_nSrc, total_nT = self._storageShape(loc)
|
||||
nSrc = np.ones(total_nSrc, dtype=bool)[srcInd].sum()
|
||||
nT = np.ones(total_nT, dtype=bool)[timeInd].sum()
|
||||
shape = nP, nSrc, nT
|
||||
if deflate:
|
||||
shape = tuple([s for s in shape if s > 1])
|
||||
if len(shape) == 1:
|
||||
shape = shape + (1,)
|
||||
return shape
|
||||
|
||||
def _setField(self, field, val, name, ind):
|
||||
srcInd, timeInd = ind
|
||||
shape = self._correctShape(name, ind)
|
||||
if Utils.isScalar(val):
|
||||
field[:,srcInd,timeInd] = val
|
||||
return
|
||||
if val.size != np.array(shape).prod():
|
||||
raise ValueError('Incorrect size for data.')
|
||||
correctShape = field[:,srcInd,timeInd].shape
|
||||
field[:,srcInd,timeInd] = val.reshape(correctShape, order='F')
|
||||
|
||||
def _getField(self, name, ind):
|
||||
srcInd, timeInd = ind
|
||||
|
||||
if name in self._fields:
|
||||
out = self._fields[name][:,srcInd,timeInd]
|
||||
else:
|
||||
# Aliased fields
|
||||
alias, loc, func = self.aliasFields[name]
|
||||
if type(func) is str:
|
||||
assert hasattr(self, func), 'The alias field function is a string, but it does not exist in the Fields class.'
|
||||
func = getattr(self, func)
|
||||
pointerFields = self._fields[alias][:,srcInd,timeInd]
|
||||
pointerShape = self._correctShape(alias, ind)
|
||||
pointerFields = pointerFields.reshape(pointerShape, order='F')
|
||||
|
||||
timeII = np.arange(self.survey.prob.nT + 1)[timeInd]
|
||||
srcII = np.array(self.survey.srcList)[srcInd]
|
||||
srcII = srcII.tolist()
|
||||
|
||||
if timeII.size == 1:
|
||||
pointerShapeDeflated = self._correctShape(alias, ind, deflate=True)
|
||||
pointerFields = pointerFields.reshape(pointerShapeDeflated, order='F')
|
||||
out = func(pointerFields, srcII, timeII)
|
||||
else: #loop over the time steps
|
||||
nT = pointerShape[2]
|
||||
out = range(nT)
|
||||
for i, TIND_i in enumerate(timeII):
|
||||
fieldI = pointerFields[:,:,i]
|
||||
if fieldI.shape[0] == fieldI.size:
|
||||
fieldI = Utils.mkvc(fieldI, 2)
|
||||
out[i] = func(fieldI, srcII, TIND_i)
|
||||
if out[i].ndim == 1:
|
||||
out[i] = out[i][:,np.newaxis,np.newaxis]
|
||||
elif out[i].ndim == 2:
|
||||
out[i] = out[i][:,:,np.newaxis]
|
||||
out = np.concatenate(out, axis=2)
|
||||
|
||||
shape = self._correctShape(name, ind, deflate=True)
|
||||
return out.reshape(shape, order='F')
|
||||
|
||||
+33
-7
@@ -1,5 +1,6 @@
|
||||
import Utils, numpy as np, scipy.sparse as sp
|
||||
from Tests import checkDerivative
|
||||
from PropMaps import PropMap, Property
|
||||
|
||||
|
||||
class IdentityMap(object):
|
||||
@@ -22,6 +23,8 @@ class IdentityMap(object):
|
||||
:rtype: int
|
||||
:return: number of parameters in the model
|
||||
"""
|
||||
if self.mesh is None:
|
||||
return '*'
|
||||
return self.mesh.nC
|
||||
|
||||
@property
|
||||
@@ -32,8 +35,11 @@ class IdentityMap(object):
|
||||
:rtype: (int,int)
|
||||
:return: shape of the operator as a tuple
|
||||
"""
|
||||
if self.mesh is None:
|
||||
return ('*', self.nP)
|
||||
return (self.mesh.nC, self.nP)
|
||||
|
||||
|
||||
def _transform(self, m):
|
||||
"""
|
||||
Changes the model into the physical property.
|
||||
@@ -98,17 +104,17 @@ class IdentityMap(object):
|
||||
|
||||
def __mul__(self, val):
|
||||
if isinstance(val, IdentityMap):
|
||||
if not self.shape[1] == val.shape[0]:
|
||||
if not (self.shape[1] == '*' or val.shape[0] == '*') and not self.shape[1] == val.shape[0]:
|
||||
raise ValueError('Dimension mismatch in %s and %s.' % (str(self), str(val)))
|
||||
return ComboMap([self, val])
|
||||
elif isinstance(val, np.ndarray):
|
||||
if not self.shape[1] == val.shape[0]:
|
||||
if not self.shape[1] == '*' and not self.shape[1] == val.shape[0]:
|
||||
raise ValueError('Dimension mismatch in %s and np.ndarray%s.' % (str(self), str(val.shape)))
|
||||
return self._transform(val)
|
||||
raise Exception('Unrecognized data type to multiply. Try a map or a numpy.ndarray!')
|
||||
|
||||
def __str__(self):
|
||||
return "%s(%d,%d)" % (self.__class__.__name__, self.shape[0], self.shape[1])
|
||||
return "%s(%s,%s)" % (self.__class__.__name__, self.shape[0], self.shape[1])
|
||||
|
||||
class ComboMap(IdentityMap):
|
||||
"""Combination of various maps."""
|
||||
@@ -119,10 +125,10 @@ class ComboMap(IdentityMap):
|
||||
self.maps = []
|
||||
for ii, m in enumerate(maps):
|
||||
assert isinstance(m, IdentityMap), 'Unrecognized data type, inherit from an IdentityMap or ComboMap!'
|
||||
if ii > 0 and not self.shape[1] == m.shape[0]:
|
||||
if ii > 0 and not (self.shape[1] == '*' or m.shape[0] == '*') and not self.shape[1] == m.shape[0]:
|
||||
prev = self.maps[-1]
|
||||
errArgs = (prev.__name__, prev.shape[0], prev.shape[1], m.__name__, m.shape[0], m.shape[1])
|
||||
raise ValueError('Dimension mismatch in map[%s] (%i, %i) and map[%s] (%i, %i).' % errArgs)
|
||||
errArgs = (prev.__class__.__name__, prev.shape[0], prev.shape[1], m.__class__.__name__, m.shape[0], m.shape[1])
|
||||
raise ValueError('Dimension mismatch in map[%s] (%s, %s) and map[%s] (%s, %s).' % errArgs)
|
||||
|
||||
if isinstance(m, ComboMap):
|
||||
self.maps += m.maps
|
||||
@@ -155,7 +161,7 @@ class ComboMap(IdentityMap):
|
||||
return deriv
|
||||
|
||||
def __str__(self):
|
||||
return 'ComboMap[%s]%s' % (' * '.join([m.__str__() for m in self.maps]), str(self.shape))
|
||||
return 'ComboMap[%s](%s,%s)' % (' * '.join([m.__str__() for m in self.maps]), self.shape[0], self.shape[1])
|
||||
|
||||
|
||||
class ExpMap(IdentityMap):
|
||||
@@ -220,6 +226,26 @@ class ExpMap(IdentityMap):
|
||||
"""
|
||||
return Utils.sdiag(np.exp(Utils.mkvc(m)))
|
||||
|
||||
class ReciprocalMap(IdentityMap):
|
||||
"""
|
||||
Reciprocal mapping. For example, electrical resistivity and conductivity.
|
||||
|
||||
.. math::
|
||||
|
||||
\\rho = \\frac{1}{\sigma}
|
||||
|
||||
"""
|
||||
def _transform(self, m):
|
||||
return 1.0 / Utils.mkvc(m)
|
||||
|
||||
def inverse(self, D):
|
||||
return 1.0 / Utils.mkvc(m)
|
||||
|
||||
def deriv(self, m):
|
||||
# TODO: if this is a tensor, you might have a problem.
|
||||
return Utils.sdiag( - Utils.mkvc(m)**(-2) )
|
||||
|
||||
|
||||
|
||||
class LogMap(IdentityMap):
|
||||
"""
|
||||
|
||||
@@ -10,24 +10,24 @@ normalize2D = lambda x: x/np.kron(np.ones((1, 2)), Utils.mkvc(length2D(x), 2))
|
||||
normalize3D = lambda x: x/np.kron(np.ones((1, 3)), Utils.mkvc(length3D(x), 2))
|
||||
|
||||
|
||||
class LogicallyRectMesh(BaseRectangularMesh, DiffOperators, InnerProducts):
|
||||
class CurvilinearMesh(BaseRectangularMesh, DiffOperators, InnerProducts):
|
||||
"""
|
||||
LogicallyRectMesh is a mesh class that deals with logically rectangular meshes.
|
||||
CurvilinearMesh is a mesh class that deals with curvilinear meshes.
|
||||
|
||||
Example of a logically rectangular mesh:
|
||||
Example of a curvilinear mesh:
|
||||
|
||||
.. plot::
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
X, Y = Utils.exampleLrmGrid([3,3],'rotate')
|
||||
M = Mesh.LogicallyRectMesh([X, Y])
|
||||
M = Mesh.CurvilinearMesh([X, Y])
|
||||
M.plotGrid(showIt=True)
|
||||
"""
|
||||
|
||||
__metaclass__ = Utils.SimPEGMetaClass
|
||||
|
||||
_meshType = 'LRM'
|
||||
_meshType = 'Curv'
|
||||
|
||||
def __init__(self, nodes):
|
||||
assert type(nodes) == list, "'nodes' variable must be a list of np.ndarray"
|
||||
@@ -38,7 +38,7 @@ class LogicallyRectMesh(BaseRectangularMesh, DiffOperators, InnerProducts):
|
||||
assert nodes_i.shape == nodes[0].shape, ("nodes[%i] is not the same shape as nodes[0]" % i)
|
||||
|
||||
assert len(nodes[0].shape) == len(nodes), "Dimension mismatch"
|
||||
assert len(nodes[0].shape) > 1, "Not worth using LRM for a 1D mesh."
|
||||
assert len(nodes[0].shape) > 1, "Not worth using Curv for a 1D mesh."
|
||||
|
||||
BaseRectangularMesh.__init__(self, np.array(nodes[0].shape)-1, None)
|
||||
|
||||
@@ -343,7 +343,7 @@ class LogicallyRectMesh(BaseRectangularMesh, DiffOperators, InnerProducts):
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
X, Y = Utils.exampleLrmGrid([3,3],'rotate')
|
||||
M = Mesh.LogicallyRectMesh([X, Y])
|
||||
M = Mesh.CurvilinearMesh([X, Y])
|
||||
M.plotGrid(showIt=True)
|
||||
|
||||
"""
|
||||
@@ -435,9 +435,9 @@ if __name__ == '__main__':
|
||||
dee3 = True
|
||||
if dee3:
|
||||
X, Y, Z = Utils.ndgrid(h1, h2, h3, vector=False)
|
||||
M = LogicallyRectMesh([X, Y, Z])
|
||||
M = CurvilinearMesh([X, Y, Z])
|
||||
else:
|
||||
X, Y = Utils.ndgrid(h1, h2, vector=False)
|
||||
M = LogicallyRectMesh([X, Y])
|
||||
M = CurvilinearMesh([X, Y])
|
||||
|
||||
print M.r(M.normals, 'F', 'Fx', 'V')
|
||||
@@ -328,7 +328,7 @@ class InnerProducts(object):
|
||||
iijj = ndgrid(i, j)
|
||||
ii, jj = iijj[:, 0], iijj[:, 1]
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
fN1 = M.r(M.normals, 'F', 'Fx', 'M')
|
||||
fN2 = M.r(M.normals, 'F', 'Fy', 'M')
|
||||
|
||||
@@ -353,7 +353,7 @@ class InnerProducts(object):
|
||||
|
||||
PXX = sp.csr_matrix((np.ones(2*M.nC), (range(2*M.nC), IND)), shape=(2*M.nC, M.nF))
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
I2x2 = inv2X2BlockDiagonal(getSubArray(fN1[0], [i + posFx, j]), getSubArray(fN1[1], [i + posFx, j]),
|
||||
getSubArray(fN2[0], [i, j + posFy]), getSubArray(fN2[1], [i, j + posFy]))
|
||||
PXX = I2x2 * PXX
|
||||
@@ -376,7 +376,7 @@ class InnerProducts(object):
|
||||
iijjkk = ndgrid(i, j, k)
|
||||
ii, jj, kk = iijjkk[:, 0], iijjkk[:, 1], iijjkk[:, 2]
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
fN1 = M.r(M.normals, 'F', 'Fx', 'M')
|
||||
fN2 = M.r(M.normals, 'F', 'Fy', 'M')
|
||||
fN3 = M.r(M.normals, 'F', 'Fz', 'M')
|
||||
@@ -410,7 +410,7 @@ class InnerProducts(object):
|
||||
|
||||
PXXX = sp.coo_matrix((np.ones(3*M.nC), (range(3*M.nC), IND)), shape=(3*M.nC, M.nF)).tocsr()
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
I3x3 = inv3X3BlockDiagonal(getSubArray(fN1[0], [i + posX, j, k]), getSubArray(fN1[1], [i + posX, j, k]), getSubArray(fN1[2], [i + posX, j, k]),
|
||||
getSubArray(fN2[0], [i, j + posY, k]), getSubArray(fN2[1], [i, j + posY, k]), getSubArray(fN2[2], [i, j + posY, k]),
|
||||
getSubArray(fN3[0], [i, j, k + posZ]), getSubArray(fN3[1], [i, j, k + posZ]), getSubArray(fN3[2], [i, j, k + posZ]))
|
||||
@@ -432,7 +432,7 @@ class InnerProducts(object):
|
||||
iijj = ndgrid(i, j)
|
||||
ii, jj = iijj[:, 0], iijj[:, 1]
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
eT1 = M.r(M.tangents, 'E', 'Ex', 'M')
|
||||
eT2 = M.r(M.tangents, 'E', 'Ey', 'M')
|
||||
|
||||
@@ -452,7 +452,7 @@ class InnerProducts(object):
|
||||
|
||||
PXX = sp.coo_matrix((np.ones(2*M.nC), (range(2*M.nC), IND)), shape=(2*M.nC, M.nE)).tocsr()
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
I2x2 = inv2X2BlockDiagonal(getSubArray(eT1[0], [i, j + posX]), getSubArray(eT1[1], [i, j + posX]),
|
||||
getSubArray(eT2[0], [i + posY, j]), getSubArray(eT2[1], [i + posY, j]))
|
||||
PXX = I2x2 * PXX
|
||||
@@ -466,7 +466,7 @@ class InnerProducts(object):
|
||||
iijjkk = ndgrid(i, j, k)
|
||||
ii, jj, kk = iijjkk[:, 0], iijjkk[:, 1], iijjkk[:, 2]
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
eT1 = M.r(M.tangents, 'E', 'Ex', 'M')
|
||||
eT2 = M.r(M.tangents, 'E', 'Ey', 'M')
|
||||
eT3 = M.r(M.tangents, 'E', 'Ez', 'M')
|
||||
@@ -495,7 +495,7 @@ class InnerProducts(object):
|
||||
|
||||
PXXX = sp.coo_matrix((np.ones(3*M.nC), (range(3*M.nC), IND)), shape=(3*M.nC, M.nE)).tocsr()
|
||||
|
||||
if M._meshType == 'LRM':
|
||||
if M._meshType == 'Curv':
|
||||
I3x3 = inv3X3BlockDiagonal(getSubArray(eT1[0], [i, j + posX[0], k + posX[1]]), getSubArray(eT1[1], [i, j + posX[0], k + posX[1]]), getSubArray(eT1[2], [i, j + posX[0], k + posX[1]]),
|
||||
getSubArray(eT2[0], [i + posY[0], j, k + posY[1]]), getSubArray(eT2[1], [i + posY[0], j, k + posY[1]]), getSubArray(eT2[2], [i + posY[0], j, k + posY[1]]),
|
||||
getSubArray(eT3[0], [i + posZ[0], j + posZ[1], k]), getSubArray(eT3[1], [i + posZ[0], j + posZ[1], k]), getSubArray(eT3[2], [i + posZ[0], j + posZ[1], k]))
|
||||
|
||||
+6
-5
@@ -328,6 +328,7 @@ class TensorView(object):
|
||||
v = getattr(np,view)(v) # e.g. np.real(v)
|
||||
if clim is None:
|
||||
clim = [v.min(),v.max()]
|
||||
v = np.ma.masked_where(np.isnan(v), v)
|
||||
out += (ax.pcolormesh(self.vectorNx, self.vectorNy, v.T, vmin=clim[0], vmax=clim[1], **pcolorOpts),)
|
||||
elif view in ['vec']:
|
||||
U, V = self.r(v.reshape((self.nC,-1), order='F'), 'CC', 'CC', 'M')
|
||||
@@ -576,11 +577,11 @@ class CylView(object):
|
||||
def plotImage(self, *args, **kwargs):
|
||||
return self._plotCylTensorMesh('plotImage', *args, **kwargs)
|
||||
|
||||
class LomView(object):
|
||||
class CurvView(object):
|
||||
"""
|
||||
Provides viewing functions for LogicallyOrthogonalMesh
|
||||
Provides viewing functions for CurvilinearMesh
|
||||
|
||||
This class is inherited by LogicallyOrthogonalMesh
|
||||
This class is inherited by CurvilinearMesh
|
||||
|
||||
"""
|
||||
def __init__(self):
|
||||
@@ -594,8 +595,8 @@ class LomView(object):
|
||||
:include-source:
|
||||
|
||||
from SimPEG import Mesh, Utils
|
||||
X, Y = Utils.exampleLomGird([3,3],'rotate')
|
||||
M = Mesh.LogicallyOrthogonalMesh([X, Y])
|
||||
X, Y = Utils.exampleCurvGird([3,3],'rotate')
|
||||
M = Mesh.CurvilinearMesh([X, Y])
|
||||
M.plotGrid(showIt=True)
|
||||
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from TensorMesh import TensorMesh
|
||||
from CylMesh import CylMesh
|
||||
from LogicallyRectMesh import LogicallyRectMesh
|
||||
from CurvilinearMesh import CurvilinearMesh
|
||||
from TreeMesh import TreeMesh
|
||||
from BaseMesh import BaseMesh
|
||||
|
||||
+2
-2
@@ -31,5 +31,5 @@ class Model(np.ndarray):
|
||||
@property
|
||||
def transformDeriv(self):
|
||||
if getattr(self, '_transformDeriv', None) is None:
|
||||
self.deriv = self.mapping.deriv(self.view(np.ndarray))
|
||||
return self.deriv
|
||||
self._transformDeriv = self.mapping.deriv(self.view(np.ndarray))
|
||||
return self._transformDeriv
|
||||
|
||||
@@ -97,6 +97,8 @@ class Minimize(object):
|
||||
tolG = 1e-1 #: Tolerance on gradient norm
|
||||
eps = 1e-5 #: Small value
|
||||
|
||||
stopNextIteration = False #: Stops the optimization program nicely.
|
||||
|
||||
debug = False #: Print debugging information
|
||||
debugLS = False #: Print debugging information for the line-search
|
||||
|
||||
@@ -186,6 +188,7 @@ class Minimize(object):
|
||||
xt, caught = self.modifySearchDirectionBreak(p)
|
||||
if not caught: return self.xc
|
||||
self.doEndIteration(xt)
|
||||
if self.stopNextIteration: break
|
||||
|
||||
self.printDone()
|
||||
self.finish()
|
||||
@@ -210,6 +213,7 @@ class Minimize(object):
|
||||
|
||||
self.iter = 0
|
||||
self.iterLS = 0
|
||||
self.stopNextIteration = False
|
||||
|
||||
x0 = self.projection(x0) # ensure that we start of feasible.
|
||||
self.x0 = x0
|
||||
|
||||
+19
-276
@@ -1,279 +1,7 @@
|
||||
import Utils, Survey, Models, numpy as np, scipy.sparse as sp
|
||||
Solver = Utils.SolverUtils.Solver
|
||||
import Maps, Mesh
|
||||
|
||||
|
||||
class Fields(object):
|
||||
"""Fancy Field Storage
|
||||
|
||||
u[:,'phi'] = phi
|
||||
print u[src0,'phi']
|
||||
|
||||
"""
|
||||
|
||||
knownFields = None #: Known fields, a dict with locations, e.g. {"e": "E", "phi": "CC"}
|
||||
aliasFields = None #: Aliased fields, a dict with [alias, location, function], e.g. {"b":["e","F",lambda(F,e,ind)]}
|
||||
dtype = float #: dtype is the type of the storage matrix. This can be a dictionary.
|
||||
|
||||
def __init__(self, mesh, survey, **kwargs):
|
||||
self.survey = survey
|
||||
self.mesh = mesh
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
self._fields = {}
|
||||
|
||||
if self.knownFields is None:
|
||||
raise Exception('knownFields cannot be set to None')
|
||||
if self.aliasFields is None:
|
||||
self.aliasFields = {}
|
||||
|
||||
allFields = [k for k in self.knownFields] + [a for a in self.aliasFields]
|
||||
assert len(allFields) == len(set(allFields)), 'Aliased fields and Known Fields have overlapping definitions.'
|
||||
self.startup()
|
||||
|
||||
def startup(self):
|
||||
pass
|
||||
|
||||
@property
|
||||
def approxSize(self):
|
||||
"""The approximate cost to storing all of the known fields."""
|
||||
sz = 0.0
|
||||
for f in self.knownFields:
|
||||
loc =self.knownFields[f]
|
||||
sz += np.array(self._storageShape(loc)).prod()*8.0/(1024**2)
|
||||
return "%e MB"%sz
|
||||
|
||||
def _storageShape(self, loc):
|
||||
nSrc = self.survey.nSrc
|
||||
|
||||
nP = {'CC': self.mesh.nC,
|
||||
'N': self.mesh.nN,
|
||||
'F': self.mesh.nF,
|
||||
'E': self.mesh.nE}[loc]
|
||||
|
||||
return (nP, nSrc)
|
||||
|
||||
def _initStore(self, name):
|
||||
if name in self._fields:
|
||||
return self._fields[name]
|
||||
|
||||
assert name in self.knownFields, 'field name is not known.'
|
||||
|
||||
loc = self.knownFields[name]
|
||||
|
||||
if type(self.dtype) is dict:
|
||||
dtype = self.dtype[name]
|
||||
else:
|
||||
dtype = self.dtype
|
||||
field = np.zeros(self._storageShape(loc), dtype=dtype)
|
||||
|
||||
self._fields[name] = field
|
||||
|
||||
return field
|
||||
|
||||
def _srcIndex(self, srcTestList):
|
||||
if type(srcTestList) is slice:
|
||||
ind = srcTestList
|
||||
else:
|
||||
if type(srcTestList) is not list:
|
||||
srcTestList = [srcTestList]
|
||||
for srcTest in srcTestList:
|
||||
if srcTest not in self.survey.srcList:
|
||||
raise KeyError('Invalid Source, not in survey list.')
|
||||
|
||||
ind = np.in1d(self.survey.srcList, srcTestList)
|
||||
return ind
|
||||
|
||||
def _nameIndex(self, name, accessType):
|
||||
|
||||
if type(name) is slice:
|
||||
assert name == slice(None,None,None), 'Fancy field name slicing is not supported... yet.'
|
||||
name = None
|
||||
|
||||
if name is None:
|
||||
return
|
||||
if accessType=='set' and name not in self.knownFields:
|
||||
if name in self.aliasFields:
|
||||
raise KeyError("Invalid field name (%s) for setter, you can't set an aliased property"%name)
|
||||
else:
|
||||
raise KeyError('Invalid field name (%s) for setter'%name)
|
||||
|
||||
elif accessType=='get' and (name not in self.knownFields and name not in self.aliasFields):
|
||||
raise KeyError('Invalid field name (%s) for getter'%name)
|
||||
return name
|
||||
|
||||
def _indexAndNameFromKey(self, key, accessType):
|
||||
if type(key) is not tuple:
|
||||
key = (key,)
|
||||
if len(key) == 1:
|
||||
key += (None,)
|
||||
|
||||
assert len(key) == 2, 'must be [Src, fieldName]'
|
||||
|
||||
srcTestList, name = key
|
||||
name = self._nameIndex(name, accessType)
|
||||
ind = self._srcIndex(srcTestList)
|
||||
return ind, name
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
ind, name = self._indexAndNameFromKey(key, 'set')
|
||||
if name is None:
|
||||
freq = key
|
||||
assert type(value) is dict, 'New fields must be a dictionary, if field is not specified.'
|
||||
newFields = value
|
||||
elif name in self.knownFields:
|
||||
newFields = {name: value}
|
||||
else:
|
||||
raise Exception('Unknown setter')
|
||||
|
||||
for name in newFields:
|
||||
field = self._initStore(name)
|
||||
self._setField(field, newFields[name], name, ind)
|
||||
|
||||
def __getitem__(self, key):
|
||||
ind, name = self._indexAndNameFromKey(key, 'get')
|
||||
if name is None:
|
||||
out = {}
|
||||
for name in self._fields:
|
||||
out[name] = self._getField(name, ind)
|
||||
return out
|
||||
return self._getField(name, ind)
|
||||
|
||||
def _setField(self, field, val, name, ind):
|
||||
if isinstance(val, np.ndarray) and (field.shape[1] == 1 or val.ndim == 1):
|
||||
val = Utils.mkvc(val,2)
|
||||
field[:,ind] = val
|
||||
|
||||
def _getField(self, name, ind):
|
||||
if name in self._fields:
|
||||
out = self._fields[name][:,ind]
|
||||
else:
|
||||
# Aliased fields
|
||||
alias, loc, func = self.aliasFields[name]
|
||||
|
||||
srcII = np.array(self.survey.srcList)[ind]
|
||||
if isinstance(srcII, np.ndarray):
|
||||
srcII = srcII.tolist()
|
||||
if len(srcII) == 1:
|
||||
srcII = srcII[0]
|
||||
|
||||
if type(func) is str:
|
||||
assert hasattr(self, func), 'The alias field function is a string, but it does not exist in the Fields class.'
|
||||
func = getattr(self, func)
|
||||
out = func(self._fields[alias][:,ind], srcII)
|
||||
|
||||
if out.shape[1] == 1:
|
||||
out = Utils.mkvc(out)
|
||||
return out
|
||||
|
||||
def __contains__(self, other):
|
||||
if other in self.aliasFields:
|
||||
other = self.aliasFields[other][0]
|
||||
return self._fields.__contains__(other)
|
||||
|
||||
|
||||
class TimeFields(Fields):
|
||||
"""Fancy Field Storage for time domain problems
|
||||
|
||||
u[:,'phi', timeInd] = phi
|
||||
print u[src0,'phi']
|
||||
|
||||
"""
|
||||
|
||||
def _storageShape(self, loc):
|
||||
nP = {'CC': self.mesh.nC,
|
||||
'N': self.mesh.nN,
|
||||
'F': self.mesh.nF,
|
||||
'E': self.mesh.nE}[loc]
|
||||
nSrc = self.survey.nSrc
|
||||
nT = self.survey.prob.nT + 1
|
||||
return (nP, nSrc, nT)
|
||||
|
||||
def _indexAndNameFromKey(self, key, accessType):
|
||||
if type(key) is not tuple:
|
||||
key = (key,)
|
||||
if len(key) == 1:
|
||||
key += (None,)
|
||||
if len(key) == 2:
|
||||
key += (slice(None,None,None),)
|
||||
|
||||
assert len(key) == 3, 'must be [Src, fieldName, times]'
|
||||
|
||||
srcTestList, name, timeInd = key
|
||||
|
||||
name = self._nameIndex(name, accessType)
|
||||
srcInd = self._srcIndex(srcTestList)
|
||||
|
||||
return (srcInd, timeInd), name
|
||||
|
||||
def _correctShape(self, name, ind, deflate=False):
|
||||
srcInd, timeInd = ind
|
||||
if name in self.knownFields:
|
||||
loc = self.knownFields[name]
|
||||
else:
|
||||
loc = self.aliasFields[name][1]
|
||||
nP, total_nSrc, total_nT = self._storageShape(loc)
|
||||
nSrc = np.ones(total_nSrc, dtype=bool)[srcInd].sum()
|
||||
nT = np.ones(total_nT, dtype=bool)[timeInd].sum()
|
||||
shape = nP, nSrc, nT
|
||||
if deflate:
|
||||
shape = tuple([s for s in shape if s > 1])
|
||||
return shape
|
||||
|
||||
def _setField(self, field, val, name, ind):
|
||||
srcInd, timeInd = ind
|
||||
shape = self._correctShape(name, ind)
|
||||
if Utils.isScalar(val):
|
||||
field[:,srcInd,timeInd] = val
|
||||
return
|
||||
if val.size != np.array(shape).prod():
|
||||
raise ValueError('Incorrect size for data.')
|
||||
correctShape = field[:,srcInd,timeInd].shape
|
||||
field[:,srcInd,timeInd] = val.reshape(correctShape, order='F')
|
||||
|
||||
def _getField(self, name, ind):
|
||||
srcInd, timeInd = ind
|
||||
|
||||
if name in self._fields:
|
||||
out = self._fields[name][:,srcInd,timeInd]
|
||||
else:
|
||||
# Aliased fields
|
||||
alias, loc, func = self.aliasFields[name]
|
||||
if type(func) is str:
|
||||
assert hasattr(self, func), 'The alias field function is a string, but it does not exist in the Fields class.'
|
||||
func = getattr(self, func)
|
||||
pointerFields = self._fields[alias][:,srcInd,timeInd]
|
||||
pointerShape = self._correctShape(alias, ind)
|
||||
pointerFields = pointerFields.reshape(pointerShape, order='F')
|
||||
|
||||
timeII = np.arange(self.survey.prob.nT + 1)[timeInd]
|
||||
srcII = np.array(self.survey.srcList)[srcInd]
|
||||
if isinstance(srcII, np.ndarray):
|
||||
srcII = srcII.tolist()
|
||||
if len(srcII) == 1:
|
||||
srcII = srcII[0]
|
||||
|
||||
if timeII.size == 1:
|
||||
pointerShapeDeflated = self._correctShape(alias, ind, deflate=True)
|
||||
pointerFields = pointerFields.reshape(pointerShapeDeflated, order='F')
|
||||
out = func(pointerFields, srcII, timeII)
|
||||
else: #loop over the time steps
|
||||
nT = pointerShape[2]
|
||||
out = range(nT)
|
||||
for i, TIND_i in enumerate(timeII):
|
||||
fieldI = pointerFields[:,:,i]
|
||||
if fieldI.ndim == 2 and fieldI.shape[1] == 1:
|
||||
fieldI = Utils.mkvc(fieldI)
|
||||
out[i] = func(fieldI, srcII, TIND_i)
|
||||
if out[i].ndim == 1:
|
||||
out[i] = out[i][:,np.newaxis,np.newaxis]
|
||||
elif out[i].ndim == 2:
|
||||
out[i] = out[i][:,:,np.newaxis]
|
||||
out = np.concatenate(out, axis=2)
|
||||
|
||||
shape = self._correctShape(name, ind, deflate=True)
|
||||
return out.reshape(shape, order='F')
|
||||
|
||||
|
||||
from Fields import Fields, TimeFields
|
||||
|
||||
class BaseProblem(object):
|
||||
"""
|
||||
@@ -290,15 +18,27 @@ class BaseProblem(object):
|
||||
Solver = Solver #: A SimPEG Solver class.
|
||||
solverOpts = {} #: Sovler options as a kwarg dict
|
||||
|
||||
mapping = None #: A SimPEG.Map instance.
|
||||
mesh = None #: A SimPEG.Mesh instance.
|
||||
|
||||
PropMap = None #: A SimPEG PropertyMap class.
|
||||
|
||||
@property
|
||||
def mapping(self):
|
||||
"A SimPEG.Map instance or a property map is PropMap is not None"
|
||||
return getattr(self, '_mapping', None)
|
||||
@mapping.setter
|
||||
def mapping(self, val):
|
||||
if self.PropMap is None:
|
||||
val._assertMatchesPair(self.mapPair)
|
||||
self._mapping = val
|
||||
else:
|
||||
self._mapping = self.PropMap(val)
|
||||
|
||||
def __init__(self, mesh, mapping=None, **kwargs):
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
assert isinstance(mesh, Mesh.BaseMesh), "mesh must be a SimPEG.Mesh object."
|
||||
self.mesh = mesh
|
||||
self.mapping = mapping or Maps.IdentityMap(mesh)
|
||||
self.mapping._assertMatchesPair(self.mapPair)
|
||||
|
||||
@property
|
||||
def survey(self):
|
||||
@@ -334,7 +74,10 @@ class BaseProblem(object):
|
||||
def curModel(self, value):
|
||||
if value is self.curModel:
|
||||
return # it is the same!
|
||||
self._curModel = Models.Model(value, self.mapping)
|
||||
if self.PropMap is not None:
|
||||
self._curModel = self.mapping(value)
|
||||
else:
|
||||
self._curModel = Models.Model(value, self.mapping)
|
||||
for prop in self.deleteTheseOnModelUpdate:
|
||||
if hasattr(self, prop):
|
||||
delattr(self, prop)
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
import Utils, Maps, numpy as np, scipy.sparse as sp
|
||||
|
||||
class Property(object):
|
||||
|
||||
name = ''
|
||||
doc = ''
|
||||
|
||||
defaultVal = None
|
||||
defaultInvProp = False
|
||||
|
||||
def __init__(self, doc, **kwargs):
|
||||
# Set the default after all other params are set
|
||||
self.doc = doc
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
@property
|
||||
def propertyLink(self):
|
||||
"Can be something like: ('sigma', Maps.ReciprocalMap)"
|
||||
return getattr(self, '_propertyLink', None)
|
||||
@propertyLink.setter
|
||||
def propertyLink(self, value):
|
||||
assert type(value) is tuple and len(value) == 2 and type(value[0]) is str and issubclass(value[1], Maps.IdentityMap), 'Use format: ("%s", Maps.ReciprocalMap)'%self.name
|
||||
self._propertyLink = value
|
||||
|
||||
def _getMapProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
return getattr(self, '_%sMap'%prop.name, None)
|
||||
def fset(self, val):
|
||||
if prop.propertyLink is not None:
|
||||
linkName, linkMap = prop.propertyLink
|
||||
assert getattr(self, '%sMap'%linkName, None) is None, 'Cannot set both sides of a linked property.'
|
||||
# TODO: Check if the mapping can be correct
|
||||
setattr(self, '_%sMap'%prop.name, val)
|
||||
return property(fget=fget, fset=fset, doc=prop.doc)
|
||||
|
||||
def _getIndexProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
return getattr(self, '_%sIndex'%prop.name, slice(None))
|
||||
def fset(self, val):
|
||||
setattr(self, '_%sIndex'%prop.name, val)
|
||||
return property(fget=fget, fset=fset, doc=prop.doc)
|
||||
|
||||
def _getProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
mapping = getattr(self, '%sMap'%prop.name)
|
||||
if mapping is None and prop.propertyLink is None:
|
||||
return prop.defaultVal
|
||||
|
||||
if mapping is None and prop.propertyLink is not None:
|
||||
linkName, linkMapClass = prop.propertyLink
|
||||
linkMap = linkMapClass(None)
|
||||
if getattr(self, '%sMap'%linkName, None) is None:
|
||||
return prop.defaultVal
|
||||
m = getattr(self, '%s'%linkName)
|
||||
return linkMap * m
|
||||
|
||||
m = getattr(self, '%sModel'%prop.name)
|
||||
return mapping * m
|
||||
return property(fget=fget)
|
||||
|
||||
def _getModelDerivProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
mapping = getattr(self, '%sMap'%prop.name)
|
||||
if mapping is None and prop.propertyLink is None:
|
||||
return None
|
||||
|
||||
if mapping is None and prop.propertyLink is not None:
|
||||
linkName, linkMapClass = prop.propertyLink
|
||||
linkedMap = getattr(self, '%sMap'%linkName)
|
||||
if linkedMap is None:
|
||||
return None
|
||||
linkMap = linkMapClass(None) * linkedMap
|
||||
m = getattr(self, '%s'%linkName)
|
||||
return linkMap.deriv( m )
|
||||
|
||||
m = getattr(self, '%sModel'%prop.name)
|
||||
return mapping.deriv( m )
|
||||
return property(fget=fget)
|
||||
|
||||
def _getModelProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
mapping = getattr(self, '%sMap'%prop.name)
|
||||
if mapping is None:
|
||||
return None
|
||||
index = getattr(self.propMap, '%sIndex'%prop.name)
|
||||
return self.vector[index]
|
||||
return property(fget=fget)
|
||||
|
||||
def _getModelProjProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
mapping = getattr(self, '%sMap'%prop.name)
|
||||
if mapping is None:
|
||||
return None
|
||||
inds = getattr(self.propMap, '%sIndex'%prop.name)
|
||||
if type(inds) is slice:
|
||||
inds = range(*inds.indices(self.nP))
|
||||
nI, nP = len(inds),self.nP
|
||||
return sp.csr_matrix((np.ones(nI), (range(nI), inds) ), shape=(nI, nP))
|
||||
return property(fget=fget)
|
||||
|
||||
def _getModelMapProperty(self):
|
||||
prop = self
|
||||
def fget(self):
|
||||
return getattr(self.propMap, '_%sMap'%prop.name, None)
|
||||
return property(fget=fget)
|
||||
|
||||
|
||||
|
||||
class PropModel(object):
|
||||
def __init__(self, propMap, vector):
|
||||
self.propMap = propMap
|
||||
self.vector = vector
|
||||
assert len(self.vector) == self.nP
|
||||
|
||||
@property
|
||||
def nP(self):
|
||||
inds = []
|
||||
if getattr(self, '_nP', None) is None:
|
||||
for name in self.propMap._properties:
|
||||
index = getattr(self.propMap, '%sIndex'%name, None)
|
||||
if index is not None:
|
||||
if type(index) is slice:
|
||||
inds += range(*index.indices(len(self.vector)))
|
||||
else:
|
||||
inds += list(index)
|
||||
self._nP = len(set(inds))
|
||||
return self._nP
|
||||
|
||||
def __contains__(self, val):
|
||||
return val in self.propMap
|
||||
|
||||
|
||||
|
||||
_PROPMAPCLASSREGISTRY = {}
|
||||
|
||||
class _PropMapMetaClass(type):
|
||||
def __new__(cls, name, bases, attrs):
|
||||
assert name.endswith('PropMap'), 'Please use convention: ___PropMap, e.g. ElectromagneticPropMap'
|
||||
_properties = {}
|
||||
for base in bases:
|
||||
for baseProp in getattr(base, '_properties', {}):
|
||||
_properties[baseProp] = base._properties[baseProp]
|
||||
keys = [key for key in attrs]
|
||||
for attr in keys:
|
||||
if isinstance(attrs[attr], Property):
|
||||
attrs[attr].name = attr
|
||||
attrs[attr + 'Map' ] = attrs[attr]._getMapProperty()
|
||||
attrs[attr + 'Index'] = attrs[attr]._getIndexProperty()
|
||||
_properties[attr] = attrs[attr]
|
||||
attrs.pop(attr)
|
||||
|
||||
attrs['_properties'] = _properties
|
||||
|
||||
defaultInvProps = []
|
||||
for p in _properties:
|
||||
prop = _properties[p]
|
||||
if prop.defaultInvProp:
|
||||
defaultInvProps += [p]
|
||||
if prop.propertyLink is not None:
|
||||
assert prop.propertyLink[0] in _properties, "You can only link to things that exist: '%s' is trying to link to '%s'"%(prop.name, prop.propertyLink[0])
|
||||
if len(defaultInvProps) > 1:
|
||||
raise Exception('You have more than one default inversion property: %s' % defaultInvProps)
|
||||
|
||||
newClass = super(_PropMapMetaClass, cls).__new__(cls, name, bases, attrs)
|
||||
|
||||
newClass.PropModel = cls.createPropModelClass(newClass, name, _properties)
|
||||
|
||||
_PROPMAPCLASSREGISTRY[name] = newClass
|
||||
return newClass
|
||||
|
||||
def createPropModelClass(self, name, _properties):
|
||||
|
||||
attrs = dict()
|
||||
|
||||
for attr in _properties:
|
||||
prop = _properties[attr]
|
||||
|
||||
attrs[attr ] = prop._getProperty()
|
||||
attrs[attr + 'Map' ] = prop._getModelMapProperty()
|
||||
attrs[attr + 'Proj' ] = prop._getModelProjProperty()
|
||||
attrs[attr + 'Model'] = prop._getModelProperty()
|
||||
attrs[attr + 'Deriv'] = prop._getModelDerivProperty()
|
||||
|
||||
return type(name.replace('PropMap', 'PropModel'), (PropModel, ), attrs)
|
||||
|
||||
|
||||
class PropMap(object):
|
||||
__metaclass__ = _PropMapMetaClass
|
||||
|
||||
def __init__(self, mappings):
|
||||
"""
|
||||
PropMap takes a multi parameter model and maps it to the equivalent PropModel
|
||||
"""
|
||||
if type(mappings) is dict:
|
||||
assert np.all([k in ['maps', 'slices'] for k in mappings]), 'Dict must only have properties "maps" and "slices"'
|
||||
self.setup(mappings['maps'], slices=mappings['slices'])
|
||||
elif type(mappings) is list:
|
||||
self.setup(mappings)
|
||||
elif isinstance(mappings, Maps.IdentityMap):
|
||||
self.setup([(self.defaultInvProp, mappings)])
|
||||
else:
|
||||
raise Exception('mappings must be a dict, a mapping, or a list of tuples.')
|
||||
|
||||
|
||||
def setup(self, maps, slices=None):
|
||||
"""
|
||||
Sets up the maps and slices for the PropertyMap
|
||||
|
||||
|
||||
:param list maps: [('sigma', sigmaMap), ('mu', muMap), ...]
|
||||
:param list slices: [('sigma', slice(0,nP)), ('mu', [1,2,5,6]), ...]
|
||||
|
||||
"""
|
||||
assert np.all([
|
||||
type(m) is tuple and
|
||||
len(m)==2 and
|
||||
type(m[0]) is str and
|
||||
m[0] in self._properties and
|
||||
isinstance(m[1], Maps.IdentityMap)
|
||||
for m in maps]), "Use signature: [%s]" % (', '.join(["('%s', %sMap)"%(p,p) for p in self._properties]))
|
||||
if slices is None:
|
||||
slices = dict()
|
||||
else:
|
||||
assert np.all([
|
||||
s in self._properties and
|
||||
(type(slices[s]) in [slice, list] or isinstance(slices[s], np.ndarray))
|
||||
for s in slices]), 'Slices must be for each property'
|
||||
|
||||
self.clearMaps()
|
||||
|
||||
nP = 0
|
||||
for name, mapping in maps:
|
||||
setattr(self, '%sMap'%name, mapping)
|
||||
setattr(self, '%sIndex'%name, slices.get(name, slice(nP, nP + mapping.nP)))
|
||||
nP += mapping.nP
|
||||
|
||||
@property
|
||||
def defaultInvProp(self):
|
||||
for name in self._properties:
|
||||
p = self._properties[name]
|
||||
if p.defaultInvProp:
|
||||
return p.name
|
||||
|
||||
def clearMaps(self):
|
||||
for name in self._properties:
|
||||
setattr(self, '%sMap'%name, None)
|
||||
setattr(self, '%sIndex'%name, None)
|
||||
|
||||
def __call__(self, vec):
|
||||
return self.PropModel(self, vec)
|
||||
|
||||
def __contains__(self, val):
|
||||
activeMaps = [name for name in self._properties if getattr(self, '%sMap'%name) is not None]
|
||||
return val in activeMaps
|
||||
+19
-5
@@ -1,4 +1,4 @@
|
||||
import Utils, numpy as np, scipy.sparse as sp
|
||||
import Utils, numpy as np, scipy.sparse as sp, uuid
|
||||
|
||||
|
||||
class BaseRx(object):
|
||||
@@ -13,6 +13,7 @@ class BaseRx(object):
|
||||
storeProjections = True #: Store calls to getP (organized by mesh)
|
||||
|
||||
def __init__(self, locs, rxType, **kwargs):
|
||||
self.uid = str(uuid.uuid4())
|
||||
self.locs = locs
|
||||
self.rxType = rxType
|
||||
self._Ps = {}
|
||||
@@ -119,14 +120,12 @@ class BaseSrc(object):
|
||||
rxList = None #: SimPEG Receiver List
|
||||
rxPair = BaseRx
|
||||
|
||||
def __init__(self, loc, srcType, rxList, **kwargs):
|
||||
def __init__(self, rxList, **kwargs):
|
||||
assert type(rxList) is list, 'rxList must be a list'
|
||||
for rx in rxList:
|
||||
assert isinstance(rx, self.rxPair), 'rxList must be a %s'%self.rxPair.__name__
|
||||
assert len(set(rxList)) == len(rxList), 'The rxList must be unique'
|
||||
|
||||
self.loc = loc
|
||||
self.srcType = srcType
|
||||
self.uid = str(uuid.uuid4())
|
||||
self.rxList = rxList
|
||||
Utils.setKwargs(self, **kwargs)
|
||||
|
||||
@@ -146,6 +145,7 @@ class Data(object):
|
||||
"""Fancy data storage by Src and Rx"""
|
||||
|
||||
def __init__(self, survey, v=None):
|
||||
self.uid = str(uuid.uuid4())
|
||||
self.survey = survey
|
||||
self._dataDict = {}
|
||||
for src in self.survey.srcList:
|
||||
@@ -227,6 +227,19 @@ class BaseSurvey(object):
|
||||
assert np.all([isinstance(src, self.srcPair) for src in value]), 'All sources must be instances of %s' % self.srcPair.__name__
|
||||
assert len(set(value)) == len(value), 'The srcList must be unique'
|
||||
self._srcList = value
|
||||
self._sourceOrder = dict()
|
||||
[self._sourceOrder.setdefault(src.uid, ii) for ii, src in enumerate(self._srcList)]
|
||||
|
||||
def getSourceIndex(self, sources):
|
||||
if type(sources) is not list:
|
||||
sources = [sources]
|
||||
for src in sources:
|
||||
if getattr(src,'uid',None) is None:
|
||||
raise KeyError('Source does not have a uid: %s'%str(src))
|
||||
inds = map(lambda src: self._sourceOrder.get(src.uid, None), sources)
|
||||
if None in inds:
|
||||
raise KeyError('Some of the sources specified are not in this survey. %s'%str(inds))
|
||||
return inds
|
||||
|
||||
@property
|
||||
def prob(self):
|
||||
@@ -360,3 +373,4 @@ class BaseSurvey(object):
|
||||
noise = std*abs(self.dtrue)*np.random.randn(*self.dtrue.shape)
|
||||
self.dobs = self.dtrue+noise
|
||||
self.std = self.dobs*0 + std
|
||||
return self.dobs
|
||||
|
||||
@@ -3,7 +3,7 @@ import matplotlib.pyplot as plt
|
||||
from numpy.linalg import norm
|
||||
from SimPEG.Utils import mkvc, sdiag, diagEst
|
||||
from SimPEG import Utils
|
||||
from SimPEG.Mesh import TensorMesh, LogicallyRectMesh, CylMesh
|
||||
from SimPEG.Mesh import TensorMesh, CurvilinearMesh, CylMesh
|
||||
import numpy as np
|
||||
import scipy.sparse as sp
|
||||
import unittest
|
||||
@@ -115,7 +115,7 @@ class OrderTest(unittest.TestCase):
|
||||
max_h = max([np.max(hi) for hi in self.M.h])
|
||||
return max_h
|
||||
|
||||
elif 'LRM' in self._meshType:
|
||||
elif 'Curv' in self._meshType:
|
||||
if 'uniform' in self._meshType:
|
||||
kwrd = 'rect'
|
||||
elif 'rotate' in self._meshType:
|
||||
@@ -126,10 +126,10 @@ class OrderTest(unittest.TestCase):
|
||||
raise Exception('Lom not supported for 1D')
|
||||
elif self.meshDimension == 2:
|
||||
X, Y = Utils.exampleLrmGrid([nc, nc], kwrd)
|
||||
self.M = LogicallyRectMesh([X, Y])
|
||||
self.M = CurvilinearMesh([X, Y])
|
||||
elif self.meshDimension == 3:
|
||||
X, Y, Z = Utils.exampleLrmGrid([nc, nc, nc], kwrd)
|
||||
self.M = LogicallyRectMesh([X, Y, Z])
|
||||
self.M = CurvilinearMesh([X, Y, Z])
|
||||
return 1./nc
|
||||
|
||||
def getError(self):
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.Mesh import TensorMesh, CurvilinearMesh
|
||||
from SimPEG.Utils import ndgrid
|
||||
|
||||
|
||||
class BasicCurvTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
a = np.array([1, 1, 1])
|
||||
b = np.array([1, 2])
|
||||
c = np.array([1, 4])
|
||||
gridIt = lambda h: [np.cumsum(np.r_[0, x]) for x in h]
|
||||
X, Y = ndgrid(gridIt([a, b]), vector=False)
|
||||
self.TM2 = TensorMesh([a, b])
|
||||
self.Curv2 = CurvilinearMesh([X, Y])
|
||||
X, Y, Z = ndgrid(gridIt([a, b, c]), vector=False)
|
||||
self.TM3 = TensorMesh([a, b, c])
|
||||
self.Curv3 = CurvilinearMesh([X, Y, Z])
|
||||
|
||||
def test_area_3D(self):
|
||||
test_area = np.array([1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2])
|
||||
self.assertTrue(np.all(self.Curv3.area == test_area))
|
||||
|
||||
def test_vol_3D(self):
|
||||
test_vol = np.array([1, 1, 1, 2, 2, 2, 4, 4, 4, 8, 8, 8])
|
||||
np.testing.assert_almost_equal(self.Curv3.vol, test_vol)
|
||||
self.assertTrue(True) # Pass if you get past the assertion.
|
||||
|
||||
def test_vol_2D(self):
|
||||
test_vol = np.array([1, 1, 1, 2, 2, 2])
|
||||
t1 = np.all(self.Curv2.vol == test_vol)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_edge_3D(self):
|
||||
test_edge = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])
|
||||
t1 = np.all(self.Curv3.edge == test_edge)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_edge_2D(self):
|
||||
test_edge = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2])
|
||||
t1 = np.all(self.Curv2.edge == test_edge)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_tangents(self):
|
||||
T = self.Curv2.tangents
|
||||
self.assertTrue(np.all(self.Curv2.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.Curv2.nEx)))
|
||||
self.assertTrue(np.all(self.Curv2.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.Curv2.nEx)))
|
||||
self.assertTrue(np.all(self.Curv2.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.Curv2.nEy)))
|
||||
self.assertTrue(np.all(self.Curv2.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.Curv2.nEy)))
|
||||
|
||||
T = self.Curv3.tangents
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.Curv3.nEx)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.Curv3.nEx)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ex', 'V')[2] == np.zeros(self.Curv3.nEx)))
|
||||
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.Curv3.nEy)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.Curv3.nEy)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ey', 'V')[2] == np.zeros(self.Curv3.nEy)))
|
||||
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ez', 'V')[0] == np.zeros(self.Curv3.nEz)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ez', 'V')[1] == np.zeros(self.Curv3.nEz)))
|
||||
self.assertTrue(np.all(self.Curv3.r(T, 'E', 'Ez', 'V')[2] == np.ones(self.Curv3.nEz)))
|
||||
|
||||
def test_normals(self):
|
||||
N = self.Curv2.normals
|
||||
self.assertTrue(np.all(self.Curv2.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.Curv2.nFx)))
|
||||
self.assertTrue(np.all(self.Curv2.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.Curv2.nFx)))
|
||||
self.assertTrue(np.all(self.Curv2.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.Curv2.nFy)))
|
||||
self.assertTrue(np.all(self.Curv2.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.Curv2.nFy)))
|
||||
|
||||
N = self.Curv3.normals
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.Curv3.nFx)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.Curv3.nFx)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fx', 'V')[2] == np.zeros(self.Curv3.nFx)))
|
||||
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.Curv3.nFy)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.Curv3.nFy)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fy', 'V')[2] == np.zeros(self.Curv3.nFy)))
|
||||
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fz', 'V')[0] == np.zeros(self.Curv3.nFz)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fz', 'V')[1] == np.zeros(self.Curv3.nFz)))
|
||||
self.assertTrue(np.all(self.Curv3.r(N, 'F', 'Fz', 'V')[2] == np.ones(self.Curv3.nFz)))
|
||||
|
||||
def test_grid(self):
|
||||
self.assertTrue(np.all(self.Curv2.gridCC == self.TM2.gridCC))
|
||||
self.assertTrue(np.all(self.Curv2.gridN == self.TM2.gridN))
|
||||
self.assertTrue(np.all(self.Curv2.gridFx == self.TM2.gridFx))
|
||||
self.assertTrue(np.all(self.Curv2.gridFy == self.TM2.gridFy))
|
||||
self.assertTrue(np.all(self.Curv2.gridEx == self.TM2.gridEx))
|
||||
self.assertTrue(np.all(self.Curv2.gridEy == self.TM2.gridEy))
|
||||
|
||||
self.assertTrue(np.all(self.Curv3.gridCC == self.TM3.gridCC))
|
||||
self.assertTrue(np.all(self.Curv3.gridN == self.TM3.gridN))
|
||||
self.assertTrue(np.all(self.Curv3.gridFx == self.TM3.gridFx))
|
||||
self.assertTrue(np.all(self.Curv3.gridFy == self.TM3.gridFy))
|
||||
self.assertTrue(np.all(self.Curv3.gridFz == self.TM3.gridFz))
|
||||
self.assertTrue(np.all(self.Curv3.gridEx == self.TM3.gridEx))
|
||||
self.assertTrue(np.all(self.Curv3.gridEy == self.TM3.gridEy))
|
||||
self.assertTrue(np.all(self.Curv3.gridEz == self.TM3.gridEz))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,7 +1,8 @@
|
||||
import unittest
|
||||
from SimPEG import *
|
||||
|
||||
class DataAndFieldsTest(unittest.TestCase):
|
||||
|
||||
class FieldsTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
mesh = Mesh.TensorMesh([np.ones(n)*5 for n in [10,11,12]],[0,0,-30])
|
||||
@@ -9,14 +10,14 @@ class DataAndFieldsTest(unittest.TestCase):
|
||||
XYZ = Utils.ndgrid(x,x,np.r_[0.])
|
||||
srcLoc = np.r_[0,0,0.]
|
||||
rxList0 = Survey.BaseRx(XYZ, 'exi')
|
||||
Src0 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0])
|
||||
Src0 = Survey.BaseSrc([rxList0], loc=srcLoc)
|
||||
rxList1 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src1 = Survey.BaseSrc(srcLoc, 'VMD', [rxList1])
|
||||
Src1 = Survey.BaseSrc([rxList1], loc=srcLoc)
|
||||
rxList2 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src2 = Survey.BaseSrc(srcLoc, 'VMD', [rxList2])
|
||||
Src2 = Survey.BaseSrc([rxList2], loc=srcLoc)
|
||||
rxList3 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src3 = Survey.BaseSrc(srcLoc, 'VMD', [rxList3])
|
||||
Src4 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0, rxList1, rxList2, rxList3])
|
||||
Src3 = Survey.BaseSrc([rxList3], loc=srcLoc)
|
||||
Src4 = Survey.BaseSrc([rxList0, rxList1, rxList2, rxList3], loc=srcLoc)
|
||||
srcList = [Src0,Src1,Src2,Src3,Src4]
|
||||
survey = Survey.BaseSurvey(srcList=srcList)
|
||||
self.D = Survey.Data(survey)
|
||||
@@ -26,25 +27,6 @@ class DataAndFieldsTest(unittest.TestCase):
|
||||
self.mesh = mesh
|
||||
self.XYZ = XYZ
|
||||
|
||||
def test_overlappingFields(self):
|
||||
self.assertRaises(AssertionError, Problem.Fields, self.F.mesh, self.F.survey,
|
||||
knownFields={'b':'F'},
|
||||
aliasFields={'b':['b',(lambda F, b, ind: b)]})
|
||||
|
||||
def test_data(self):
|
||||
V = []
|
||||
for src in self.D.survey.srcList:
|
||||
for rx in src.rxList:
|
||||
v = np.random.rand(rx.nD)
|
||||
V += [v]
|
||||
self.D[src, rx] = v
|
||||
self.assertTrue(np.all(v == self.D[src, rx]))
|
||||
V = np.concatenate(V)
|
||||
self.assertTrue(np.all(V == Utils.mkvc(self.D)))
|
||||
|
||||
D2 = Survey.Data(self.D.survey, V)
|
||||
self.assertTrue(np.all(Utils.mkvc(D2) == Utils.mkvc(self.D)))
|
||||
|
||||
def test_contains(self):
|
||||
F = self.F
|
||||
nSrc = F.survey.nSrc
|
||||
@@ -55,10 +37,10 @@ class DataAndFieldsTest(unittest.TestCase):
|
||||
self.assertTrue('b' not in F)
|
||||
self.assertTrue('e' in F)
|
||||
|
||||
def test_uniqueSrcs(self):
|
||||
srcs = self.D.survey.srcList
|
||||
srcs += [srcs[0]]
|
||||
self.assertRaises(AssertionError, Survey.BaseSurvey, srcList=srcs)
|
||||
def test_overlappingFields(self):
|
||||
self.assertRaises(AssertionError, Problem.Fields, self.F.mesh, self.F.survey,
|
||||
knownFields={'b':'F'},
|
||||
aliasFields={'b':['b',(lambda F, b, ind: b)]})
|
||||
|
||||
def test_SetGet(self):
|
||||
F = self.F
|
||||
@@ -80,9 +62,9 @@ class DataAndFieldsTest(unittest.TestCase):
|
||||
|
||||
b = np.random.rand(F.mesh.nF,1)
|
||||
F[self.Src0, 'b'] = b
|
||||
self.assertTrue(np.all(F[self.Src0, 'b'] == Utils.mkvc(b)))
|
||||
self.assertTrue(np.all(F[self.Src0, 'b'] == b))
|
||||
|
||||
b = np.random.rand(F.mesh.nF)
|
||||
b = np.random.rand(F.mesh.nF,1)
|
||||
F[self.Src0, 'b'] = b
|
||||
self.assertTrue(np.all(F[self.Src0, 'b'] == b))
|
||||
|
||||
@@ -96,10 +78,10 @@ class DataAndFieldsTest(unittest.TestCase):
|
||||
|
||||
b = np.random.rand(F.mesh.nF, 2)
|
||||
F[[self.Src0, self.Src1],'b'] = b
|
||||
self.assertTrue(F[self.Src0]['b'].shape == (F.mesh.nF,))
|
||||
self.assertTrue(F[self.Src0,'b'].shape == (F.mesh.nF,))
|
||||
self.assertTrue(np.all(F[self.Src0,'b'] == b[:,0]))
|
||||
self.assertTrue(np.all(F[self.Src1,'b'] == b[:,1]))
|
||||
self.assertTrue(F[self.Src0]['b'].shape == (F.mesh.nF,1))
|
||||
self.assertTrue(F[self.Src0,'b'].shape == (F.mesh.nF,1))
|
||||
self.assertTrue(np.all(F[self.Src0,'b'] == Utils.mkvc(b[:,0],2)))
|
||||
self.assertTrue(np.all(F[self.Src1,'b'] == Utils.mkvc(b[:,1],2)))
|
||||
|
||||
def test_assertions(self):
|
||||
freq = [self.Src0, self.Src1]
|
||||
@@ -122,17 +104,16 @@ class FieldsTest_Alias(unittest.TestCase):
|
||||
XYZ = Utils.ndgrid(x,x,np.r_[0.])
|
||||
srcLoc = np.r_[0,0,0.]
|
||||
rxList0 = Survey.BaseRx(XYZ, 'exi')
|
||||
Src0 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0])
|
||||
Src0 = Survey.BaseSrc([rxList0],loc=srcLoc)
|
||||
rxList1 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src1 = Survey.BaseSrc(srcLoc, 'VMD', [rxList1])
|
||||
Src1 = Survey.BaseSrc([rxList1],loc=srcLoc)
|
||||
rxList2 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src2 = Survey.BaseSrc(srcLoc, 'VMD', [rxList2])
|
||||
Src2 = Survey.BaseSrc([rxList2],loc=srcLoc)
|
||||
rxList3 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src3 = Survey.BaseSrc(srcLoc, 'VMD', [rxList3])
|
||||
Src4 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0, rxList1, rxList2, rxList3])
|
||||
Src3 = Survey.BaseSrc([rxList3],loc=srcLoc)
|
||||
Src4 = Survey.BaseSrc([rxList0, rxList1, rxList2, rxList3],loc=srcLoc)
|
||||
srcList = [Src0,Src1,Src2,Src3,Src4]
|
||||
survey = Survey.BaseSurvey(srcList=srcList)
|
||||
self.D = Survey.Data(survey)
|
||||
self.F = Problem.Fields(mesh, survey, knownFields={'e':'E'}, aliasFields={'b':['e','F',(lambda e, ind: self.F.mesh.edgeCurl * e)]})
|
||||
self.Src0 = Src0
|
||||
self.Src1 = Src1
|
||||
@@ -158,7 +139,7 @@ class FieldsTest_Alias(unittest.TestCase):
|
||||
|
||||
e = np.random.rand(F.mesh.nE,1)
|
||||
F[self.Src0, 'e'] = e
|
||||
self.assertTrue(np.all(F[self.Src0, 'b'] == F.mesh.edgeCurl * Utils.mkvc(e)))
|
||||
self.assertTrue(np.all(F[self.Src0, 'b'] == F.mesh.edgeCurl * e))
|
||||
|
||||
def f():
|
||||
F[self.Src0, 'b'] = F[self.Src0, 'b']
|
||||
@@ -166,7 +147,7 @@ class FieldsTest_Alias(unittest.TestCase):
|
||||
|
||||
def test_aliasFunction(self):
|
||||
def alias(e, ind):
|
||||
self.assertTrue(ind is self.Src0)
|
||||
self.assertTrue(ind[0] is self.Src0)
|
||||
return self.F.mesh.edgeCurl * e
|
||||
F = Problem.Fields(self.F.mesh, self.F.survey, knownFields={'e':'E'}, aliasFields={'b':['e','F',alias]})
|
||||
e = np.random.rand(F.mesh.nE,1)
|
||||
@@ -193,14 +174,14 @@ class FieldsTest_Time(unittest.TestCase):
|
||||
XYZ = Utils.ndgrid(x,x,np.r_[0.])
|
||||
srcLoc = np.r_[0,0,0.]
|
||||
rxList0 = Survey.BaseRx(XYZ, 'exi')
|
||||
Src0 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0])
|
||||
Src0 = Survey.BaseSrc([rxList0], loc=srcLoc)
|
||||
rxList1 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src1 = Survey.BaseSrc(srcLoc, 'VMD', [rxList1])
|
||||
Src1 = Survey.BaseSrc([rxList1], loc=srcLoc)
|
||||
rxList2 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src2 = Survey.BaseSrc(srcLoc, 'VMD', [rxList2])
|
||||
Src2 = Survey.BaseSrc([rxList2], loc=srcLoc)
|
||||
rxList3 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src3 = Survey.BaseSrc(srcLoc, 'VMD', [rxList3])
|
||||
Src4 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0, rxList1, rxList2, rxList3])
|
||||
Src3 = Survey.BaseSrc([rxList3], loc=srcLoc)
|
||||
Src4 = Survey.BaseSrc([rxList0, rxList1, rxList2, rxList3], loc=srcLoc)
|
||||
srcList = [Src0,Src1,Src2,Src3,Src4]
|
||||
survey = Survey.BaseSurvey(srcList=srcList)
|
||||
prob = Problem.BaseTimeProblem(mesh, timeSteps=[(10.,3), (20.,2)])
|
||||
@@ -249,7 +230,7 @@ class FieldsTest_Time(unittest.TestCase):
|
||||
|
||||
b = np.random.rand(F.mesh.nF,1,nT)
|
||||
F[self.Src0, 'b', 0] = b[:,:,0]
|
||||
self.assertTrue(np.all(F[self.Src0, 'b', 0] == b[:,0,0]))
|
||||
self.assertTrue(np.all(F[self.Src0, 'b', 0] == Utils.mkvc(b[:,0,0],2)))
|
||||
|
||||
phi = np.random.rand(F.mesh.nC,2,nT)
|
||||
F[[self.Src0,self.Src1], 'phi'] = phi
|
||||
@@ -265,10 +246,10 @@ class FieldsTest_Time(unittest.TestCase):
|
||||
self.assertTrue(F[self.Src0,'b'].shape == (F.mesh.nF,nT))
|
||||
self.assertTrue(np.all(F[self.Src0,'b'] == b[:,0,:]))
|
||||
self.assertTrue(np.all(F[self.Src1,'b'] == b[:,1,:]))
|
||||
self.assertTrue(np.all(F[self.Src0,'b',1] == b[:,0,1]))
|
||||
self.assertTrue(np.all(F[self.Src1,'b',1] == b[:,1,1]))
|
||||
self.assertTrue(np.all(F[self.Src0,'b',4] == b[:,0,4]))
|
||||
self.assertTrue(np.all(F[self.Src1,'b',4] == b[:,1,4]))
|
||||
self.assertTrue(np.all(F[self.Src0,'b',1] == Utils.mkvc(b[:,0,1],2)))
|
||||
self.assertTrue(np.all(F[self.Src1,'b',1] == Utils.mkvc(b[:,1,1],2)))
|
||||
self.assertTrue(np.all(F[self.Src0,'b',4] == Utils.mkvc(b[:,0,4],2)))
|
||||
self.assertTrue(np.all(F[self.Src1,'b',4] == Utils.mkvc(b[:,1,4],2)))
|
||||
|
||||
|
||||
b = np.random.rand(F.mesh.nF, 2, nT)
|
||||
@@ -295,14 +276,14 @@ class FieldsTest_Time_Aliased(unittest.TestCase):
|
||||
XYZ = Utils.ndgrid(x,x,np.r_[0.])
|
||||
srcLoc = np.r_[0,0,0.]
|
||||
rxList0 = Survey.BaseRx(XYZ, 'exi')
|
||||
Src0 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0])
|
||||
Src0 = Survey.BaseSrc( [rxList0],loc=srcLoc)
|
||||
rxList1 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src1 = Survey.BaseSrc(srcLoc, 'VMD', [rxList1])
|
||||
Src1 = Survey.BaseSrc( [rxList1],loc=srcLoc)
|
||||
rxList2 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src2 = Survey.BaseSrc(srcLoc, 'VMD', [rxList2])
|
||||
Src2 = Survey.BaseSrc( [rxList2],loc=srcLoc)
|
||||
rxList3 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src3 = Survey.BaseSrc(srcLoc, 'VMD', [rxList3])
|
||||
Src4 = Survey.BaseSrc(srcLoc, 'VMD', [rxList0, rxList1, rxList2, rxList3])
|
||||
Src3 = Survey.BaseSrc( [rxList3],loc=srcLoc)
|
||||
Src4 = Survey.BaseSrc( [rxList0, rxList1, rxList2, rxList3],loc=srcLoc)
|
||||
srcList = [Src0,Src1,Src2,Src3,Src4]
|
||||
survey = Survey.BaseSurvey(srcList=srcList)
|
||||
prob = Problem.BaseTimeProblem(mesh, timeSteps=[(10.,3), (20.,2)])
|
||||
@@ -344,7 +325,7 @@ class FieldsTest_Time_Aliased(unittest.TestCase):
|
||||
self.assertTrue(np.all(F[self.Src0, 'e', :] == e[:,0,:] ))
|
||||
self.assertTrue(np.all(F[self.Src1, 'e', :] == e[:,1,:] ))
|
||||
for t in range(nT):
|
||||
self.assertTrue(np.all(F[self.Src1, 'e', t] == e[:,1,t] ))
|
||||
self.assertTrue(np.all(F[self.Src1, 'e', t] == Utils.mkvc(e[:,1,t],2) ))
|
||||
|
||||
b = np.random.rand(F.mesh.nF,nT)
|
||||
F[self.Src0, 'b',:] = b
|
||||
@@ -362,7 +343,7 @@ class FieldsTest_Time_Aliased(unittest.TestCase):
|
||||
count = [0]
|
||||
def alias(e, srcInd, timeInd):
|
||||
count[0] += 1
|
||||
self.assertTrue(srcInd is self.Src0)
|
||||
self.assertTrue(srcInd[0] is self.Src0)
|
||||
return self.F.mesh.edgeCurl * e
|
||||
F = Problem.TimeFields(self.F.mesh, self.F.survey, knownFields={'e':'E'}, aliasFields={'b':['e','F',alias]})
|
||||
e = np.random.rand(F.mesh.nE,1,nT)
|
||||
@@ -1,104 +0,0 @@
|
||||
import numpy as np
|
||||
import unittest
|
||||
from SimPEG.Mesh import TensorMesh, LogicallyRectMesh
|
||||
from SimPEG.Utils import ndgrid
|
||||
|
||||
|
||||
class BasicLRMTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
a = np.array([1, 1, 1])
|
||||
b = np.array([1, 2])
|
||||
c = np.array([1, 4])
|
||||
gridIt = lambda h: [np.cumsum(np.r_[0, x]) for x in h]
|
||||
X, Y = ndgrid(gridIt([a, b]), vector=False)
|
||||
self.TM2 = TensorMesh([a, b])
|
||||
self.LRM2 = LogicallyRectMesh([X, Y])
|
||||
X, Y, Z = ndgrid(gridIt([a, b, c]), vector=False)
|
||||
self.TM3 = TensorMesh([a, b, c])
|
||||
self.LRM3 = LogicallyRectMesh([X, Y, Z])
|
||||
|
||||
def test_area_3D(self):
|
||||
test_area = np.array([1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2])
|
||||
self.assertTrue(np.all(self.LRM3.area == test_area))
|
||||
|
||||
def test_vol_3D(self):
|
||||
test_vol = np.array([1, 1, 1, 2, 2, 2, 4, 4, 4, 8, 8, 8])
|
||||
np.testing.assert_almost_equal(self.LRM3.vol, test_vol)
|
||||
self.assertTrue(True) # Pass if you get past the assertion.
|
||||
|
||||
def test_vol_2D(self):
|
||||
test_vol = np.array([1, 1, 1, 2, 2, 2])
|
||||
t1 = np.all(self.LRM2.vol == test_vol)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_edge_3D(self):
|
||||
test_edge = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])
|
||||
t1 = np.all(self.LRM3.edge == test_edge)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_edge_2D(self):
|
||||
test_edge = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2])
|
||||
t1 = np.all(self.LRM2.edge == test_edge)
|
||||
self.assertTrue(t1)
|
||||
|
||||
def test_tangents(self):
|
||||
T = self.LRM2.tangents
|
||||
self.assertTrue(np.all(self.LRM2.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LRM2.nEx)))
|
||||
self.assertTrue(np.all(self.LRM2.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LRM2.nEx)))
|
||||
self.assertTrue(np.all(self.LRM2.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LRM2.nEy)))
|
||||
self.assertTrue(np.all(self.LRM2.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LRM2.nEy)))
|
||||
|
||||
T = self.LRM3.tangents
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ex', 'V')[0] == np.ones(self.LRM3.nEx)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ex', 'V')[1] == np.zeros(self.LRM3.nEx)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ex', 'V')[2] == np.zeros(self.LRM3.nEx)))
|
||||
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ey', 'V')[0] == np.zeros(self.LRM3.nEy)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ey', 'V')[1] == np.ones(self.LRM3.nEy)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ey', 'V')[2] == np.zeros(self.LRM3.nEy)))
|
||||
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ez', 'V')[0] == np.zeros(self.LRM3.nEz)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ez', 'V')[1] == np.zeros(self.LRM3.nEz)))
|
||||
self.assertTrue(np.all(self.LRM3.r(T, 'E', 'Ez', 'V')[2] == np.ones(self.LRM3.nEz)))
|
||||
|
||||
def test_normals(self):
|
||||
N = self.LRM2.normals
|
||||
self.assertTrue(np.all(self.LRM2.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LRM2.nFx)))
|
||||
self.assertTrue(np.all(self.LRM2.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LRM2.nFx)))
|
||||
self.assertTrue(np.all(self.LRM2.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LRM2.nFy)))
|
||||
self.assertTrue(np.all(self.LRM2.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LRM2.nFy)))
|
||||
|
||||
N = self.LRM3.normals
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fx', 'V')[0] == np.ones(self.LRM3.nFx)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fx', 'V')[1] == np.zeros(self.LRM3.nFx)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fx', 'V')[2] == np.zeros(self.LRM3.nFx)))
|
||||
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fy', 'V')[0] == np.zeros(self.LRM3.nFy)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fy', 'V')[1] == np.ones(self.LRM3.nFy)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fy', 'V')[2] == np.zeros(self.LRM3.nFy)))
|
||||
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fz', 'V')[0] == np.zeros(self.LRM3.nFz)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fz', 'V')[1] == np.zeros(self.LRM3.nFz)))
|
||||
self.assertTrue(np.all(self.LRM3.r(N, 'F', 'Fz', 'V')[2] == np.ones(self.LRM3.nFz)))
|
||||
|
||||
def test_grid(self):
|
||||
self.assertTrue(np.all(self.LRM2.gridCC == self.TM2.gridCC))
|
||||
self.assertTrue(np.all(self.LRM2.gridN == self.TM2.gridN))
|
||||
self.assertTrue(np.all(self.LRM2.gridFx == self.TM2.gridFx))
|
||||
self.assertTrue(np.all(self.LRM2.gridFy == self.TM2.gridFy))
|
||||
self.assertTrue(np.all(self.LRM2.gridEx == self.TM2.gridEx))
|
||||
self.assertTrue(np.all(self.LRM2.gridEy == self.TM2.gridEy))
|
||||
|
||||
self.assertTrue(np.all(self.LRM3.gridCC == self.TM3.gridCC))
|
||||
self.assertTrue(np.all(self.LRM3.gridN == self.TM3.gridN))
|
||||
self.assertTrue(np.all(self.LRM3.gridFx == self.TM3.gridFx))
|
||||
self.assertTrue(np.all(self.LRM3.gridFy == self.TM3.gridFy))
|
||||
self.assertTrue(np.all(self.LRM3.gridFz == self.TM3.gridFz))
|
||||
self.assertTrue(np.all(self.LRM3.gridEx == self.TM3.gridEx))
|
||||
self.assertTrue(np.all(self.LRM3.gridEy == self.TM3.gridEy))
|
||||
self.assertTrue(np.all(self.LRM3.gridEz == self.TM3.gridEz))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,193 @@
|
||||
import unittest
|
||||
from SimPEG import *
|
||||
from scipy.constants import mu_0
|
||||
|
||||
|
||||
class MyPropMap(Maps.PropMap):
|
||||
sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True)
|
||||
mu = Maps.Property("Mu", defaultVal=mu_0)
|
||||
|
||||
class MyReciprocalPropMap(Maps.PropMap):
|
||||
sigma = Maps.Property("Electrical Conductivity", defaultInvProp=True, propertyLink=('rho', Maps.ReciprocalMap))
|
||||
rho = Maps.Property("Electrical Resistivity", propertyLink=('sigma', Maps.ReciprocalMap))
|
||||
mu = Maps.Property("Mu", defaultVal=mu_0, propertyLink=('mui', Maps.ReciprocalMap))
|
||||
mui = Maps.Property("Mu", defaultVal=1./mu_0, propertyLink=('mu', Maps.ReciprocalMap))
|
||||
|
||||
|
||||
class TestPropMaps(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def test_setup(self):
|
||||
expMap = Maps.ExpMap(Mesh.TensorMesh((3,)))
|
||||
assert expMap.nP == 3
|
||||
|
||||
PM1 = MyPropMap(expMap)
|
||||
PM2 = MyPropMap([('sigma', expMap)])
|
||||
PM3 = MyPropMap({'maps':[('sigma', expMap)], 'slices':{'sigma':slice(0,3)}})
|
||||
|
||||
for PM in [PM1,PM2,PM3]:
|
||||
assert PM.defaultInvProp == 'sigma'
|
||||
assert PM.sigmaMap is not None
|
||||
assert PM.sigmaMap is expMap
|
||||
assert PM.sigmaIndex == slice(0,3)
|
||||
assert getattr(PM, 'sigma', None) is None
|
||||
assert PM.muMap is None
|
||||
assert PM.muIndex is None
|
||||
|
||||
assert 'sigma' in PM
|
||||
assert 'mu' not in PM
|
||||
assert 'mui' not in PM
|
||||
|
||||
m = PM(np.r_[1.,2,3])
|
||||
|
||||
assert 'sigma' in m
|
||||
assert 'mu' not in m
|
||||
assert 'mui' not in m
|
||||
|
||||
assert m.mu == mu_0
|
||||
assert m.muModel is None
|
||||
assert m.muMap is None
|
||||
assert m.muDeriv is None
|
||||
|
||||
assert np.all(m.sigmaModel == np.r_[1.,2,3])
|
||||
assert m.sigmaMap is expMap
|
||||
assert np.all(m.sigma == np.exp(np.r_[1.,2,3]))
|
||||
assert m.sigmaDeriv is not None
|
||||
|
||||
assert m.nP == 3
|
||||
|
||||
def test_slices(self):
|
||||
expMap = Maps.ExpMap(Mesh.TensorMesh((3,)))
|
||||
PM = MyPropMap({'maps':[('sigma', expMap)], 'slices':{'sigma':[2,1,0]}})
|
||||
assert PM.sigmaIndex == [2,1,0]
|
||||
m = PM(np.r_[1.,2,3])
|
||||
assert np.all(m.sigmaModel == np.r_[3,2,1])
|
||||
assert np.all(m.sigma == np.exp(np.r_[3,2,1]))
|
||||
|
||||
def test_multiMap(self):
|
||||
m = Mesh.TensorMesh((3,))
|
||||
expMap = Maps.ExpMap(m)
|
||||
iMap = Maps.IdentityMap(m)
|
||||
PM = MyPropMap([('sigma', expMap), ('mu', iMap)])
|
||||
|
||||
pm = PM(np.r_[1.,2,3,4,5,6])
|
||||
|
||||
assert pm.nP == 6
|
||||
|
||||
assert 'sigma' in PM
|
||||
assert 'mu' in PM
|
||||
assert 'mui' not in PM
|
||||
|
||||
assert 'sigma' in pm
|
||||
assert 'mu' in pm
|
||||
assert 'mui' not in pm
|
||||
|
||||
assert np.all(pm.sigmaModel == [1.,2,3])
|
||||
assert np.all(pm.sigma == np.exp([1.,2,3]))
|
||||
assert np.all(pm.muModel == [4.,5,6])
|
||||
assert np.all(pm.mu == [4.,5,6])
|
||||
|
||||
|
||||
def test_multiMapCompressed(self):
|
||||
m = Mesh.TensorMesh((3,))
|
||||
expMap = Maps.ExpMap(m)
|
||||
iMap = Maps.IdentityMap(m)
|
||||
PM = MyPropMap({'maps':[('sigma', expMap), ('mu', iMap)],'slices':{'mu':[0,1,2]}})
|
||||
|
||||
pm = PM(np.r_[1,2.,3])
|
||||
|
||||
assert pm.nP == 3
|
||||
|
||||
assert 'sigma' in PM
|
||||
assert 'mu' in PM
|
||||
assert 'mui' not in PM
|
||||
|
||||
assert 'sigma' in pm
|
||||
assert 'mu' in pm
|
||||
assert 'mui' not in pm
|
||||
|
||||
assert np.all(pm.sigmaModel == [1,2,3])
|
||||
assert np.all(pm.sigma == np.exp([1,2,3]))
|
||||
assert np.all(pm.muModel == [1,2,3])
|
||||
assert np.all(pm.mu == [1,2,3])
|
||||
|
||||
def test_Projections(self):
|
||||
m = Mesh.TensorMesh((3,))
|
||||
iMap = Maps.IdentityMap(m)
|
||||
PM = MyReciprocalPropMap([('sigma', iMap)])
|
||||
v = np.r_[1,2.,3]
|
||||
pm = PM(v)
|
||||
|
||||
assert pm.sigmaProj is not None
|
||||
assert pm.rhoProj is None
|
||||
assert pm.muProj is None
|
||||
assert pm.muiProj is None
|
||||
|
||||
assert np.all(pm.sigmaProj * v == pm.sigmaModel)
|
||||
|
||||
def test_Links(self):
|
||||
m = Mesh.TensorMesh((3,))
|
||||
expMap = Maps.ExpMap(m)
|
||||
iMap = Maps.IdentityMap(m)
|
||||
PM = MyReciprocalPropMap([('sigma', iMap)])
|
||||
pm = PM(np.r_[1,2.,3])
|
||||
# print pm.sigma
|
||||
# print pm.sigmaMap
|
||||
assert np.all(pm.sigma == [1,2,3])
|
||||
assert np.all(pm.rho == 1./np.r_[1,2,3])
|
||||
assert pm.sigmaMap is iMap
|
||||
assert pm.rhoMap is None
|
||||
assert pm.sigmaDeriv is not None
|
||||
assert pm.rhoDeriv is not None
|
||||
|
||||
assert 'sigma' in PM
|
||||
assert 'rho' not in PM
|
||||
assert 'mu' not in PM
|
||||
assert 'mui' not in PM
|
||||
|
||||
|
||||
assert 'sigma' in pm
|
||||
assert 'rho' not in pm
|
||||
assert 'mu' not in pm
|
||||
assert 'mui' not in pm
|
||||
|
||||
assert pm.mu == mu_0
|
||||
assert pm.mui == 1.0/mu_0
|
||||
assert pm.muMap is None
|
||||
assert pm.muDeriv is None
|
||||
assert pm.muiMap is None
|
||||
assert pm.muiDeriv is None
|
||||
|
||||
PM = MyReciprocalPropMap([('rho', iMap)])
|
||||
pm = PM(np.r_[1,2.,3])
|
||||
# print pm.sigma
|
||||
# print pm.sigmaMap
|
||||
assert np.all(pm.sigma == 1./np.r_[1,2,3])
|
||||
assert np.all(pm.rho == [1,2,3])
|
||||
assert pm.sigmaMap is None
|
||||
assert pm.rhoMap is iMap
|
||||
assert pm.sigmaDeriv is not None
|
||||
assert pm.rhoDeriv is not None
|
||||
|
||||
assert 'sigma' not in PM
|
||||
assert 'rho' in PM
|
||||
assert 'mu' not in PM
|
||||
assert 'mui' not in PM
|
||||
|
||||
|
||||
assert 'sigma' not in pm
|
||||
assert 'rho' in pm
|
||||
assert 'mu' not in pm
|
||||
assert 'mui' not in pm
|
||||
|
||||
self.assertRaises(AssertionError, MyReciprocalPropMap, [('rho', iMap), ('sigma', iMap)])
|
||||
self.assertRaises(AssertionError, MyReciprocalPropMap, [('sigma', iMap), ('rho', iMap)])
|
||||
|
||||
MyReciprocalPropMap([('sigma', iMap), ('mu', iMap)]) # This should be fine
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import unittest
|
||||
from SimPEG import *
|
||||
|
||||
class TestData(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
mesh = Mesh.TensorMesh([np.ones(n)*5 for n in [10,11,12]],[0,0,-30])
|
||||
x = np.linspace(5,10,3)
|
||||
XYZ = Utils.ndgrid(x,x,np.r_[0.])
|
||||
srcLoc = np.r_[0,0,0.]
|
||||
rxList0 = Survey.BaseRx(XYZ, 'exi')
|
||||
Src0 = Survey.BaseSrc([rxList0], loc=srcLoc)
|
||||
rxList1 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src1 = Survey.BaseSrc([rxList1], loc=srcLoc)
|
||||
rxList2 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src2 = Survey.BaseSrc([rxList2], loc=srcLoc)
|
||||
rxList3 = Survey.BaseRx(XYZ, 'bxi')
|
||||
Src3 = Survey.BaseSrc([rxList3], loc=srcLoc)
|
||||
Src4 = Survey.BaseSrc([rxList0, rxList1, rxList2, rxList3], loc=srcLoc)
|
||||
srcList = [Src0,Src1,Src2,Src3,Src4]
|
||||
survey = Survey.BaseSurvey(srcList=srcList)
|
||||
self.D = Survey.Data(survey)
|
||||
|
||||
def test_data(self):
|
||||
V = []
|
||||
for src in self.D.survey.srcList:
|
||||
for rx in src.rxList:
|
||||
v = np.random.rand(rx.nD)
|
||||
V += [v]
|
||||
self.D[src, rx] = v
|
||||
self.assertTrue(np.all(v == self.D[src, rx]))
|
||||
V = np.concatenate(V)
|
||||
self.assertTrue(np.all(V == Utils.mkvc(self.D)))
|
||||
|
||||
D2 = Survey.Data(self.D.survey, V)
|
||||
self.assertTrue(np.all(Utils.mkvc(D2) == Utils.mkvc(self.D)))
|
||||
|
||||
def test_uniqueSrcs(self):
|
||||
srcs = self.D.survey.srcList
|
||||
srcs += [srcs[0]]
|
||||
self.assertRaises(AssertionError, Survey.BaseSurvey, srcList=srcs)
|
||||
|
||||
def test_sourceIndex(self):
|
||||
survey = self.D.survey
|
||||
srcs = survey.srcList
|
||||
assert survey.getSourceIndex([srcs[1],srcs[0]]) == [1,0]
|
||||
assert survey.getSourceIndex([srcs[1],srcs[2],srcs[2]]) == [1,2,2]
|
||||
SrcNotThere = Survey.BaseSrc(srcs[0].rxList, loc=np.r_[0,0,0])
|
||||
self.assertRaises(KeyError, survey.getSourceIndex, [SrcNotThere])
|
||||
self.assertRaises(KeyError, survey.getSourceIndex, [srcs[1],srcs[2],SrcNotThere])
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -7,7 +7,7 @@ from SimPEG import Utils
|
||||
class TestInnerProducts(OrderTest):
|
||||
"""Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts."""
|
||||
|
||||
meshTypes = ['uniformTensorMesh', 'uniformLRM', 'rotateLRM']
|
||||
meshTypes = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv']
|
||||
meshDimension = 3
|
||||
meshSizes = [16, 32]
|
||||
|
||||
@@ -154,7 +154,7 @@ class TestInnerProducts(OrderTest):
|
||||
class TestInnerProducts2D(OrderTest):
|
||||
"""Integrate an function over a unit cube domain using edgeInnerProducts and faceInnerProducts."""
|
||||
|
||||
meshTypes = ['uniformTensorMesh', 'uniformLRM', 'rotateLRM']
|
||||
meshTypes = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv']
|
||||
meshDimension = 2
|
||||
meshSizes = [4, 8, 16, 32, 64, 128]
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@ from TestUtils import checkDerivative
|
||||
class TestInnerProductsDerivs(unittest.TestCase):
|
||||
|
||||
def doTestFace(self, h, rep, fast, meshType, invProp=False, invMat=False):
|
||||
if meshType == 'LRM':
|
||||
if meshType == 'Curv':
|
||||
hRect = Utils.exampleLrmGrid(h,'rotate')
|
||||
mesh = Mesh.LogicallyRectMesh(hRect)
|
||||
mesh = Mesh.CurvilinearMesh(hRect)
|
||||
elif meshType == 'Tree':
|
||||
mesh = Mesh.TreeMesh(h)
|
||||
elif meshType == 'Tensor':
|
||||
@@ -24,9 +24,9 @@ class TestInnerProductsDerivs(unittest.TestCase):
|
||||
return checkDerivative(fun, sig, num=5, plotIt=False)
|
||||
|
||||
def doTestEdge(self, h, rep, fast, meshType, invProp=False, invMat=False):
|
||||
if meshType == 'LRM':
|
||||
if meshType == 'Curv':
|
||||
hRect = Utils.exampleLrmGrid(h,'rotate')
|
||||
mesh = Mesh.LogicallyRectMesh(hRect)
|
||||
mesh = Mesh.CurvilinearMesh(hRect)
|
||||
elif meshType == 'Tree':
|
||||
mesh = Mesh.TreeMesh(h)
|
||||
elif meshType == 'Tensor':
|
||||
@@ -137,65 +137,65 @@ class TestInnerProductsDerivs(unittest.TestCase):
|
||||
|
||||
|
||||
|
||||
def test_FaceIP_2D_float_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],0, False, 'LRM'))
|
||||
def test_FaceIP_3D_float_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],0, False, 'LRM'))
|
||||
def test_FaceIP_2D_isotropic_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],1, False, 'LRM'))
|
||||
def test_FaceIP_3D_isotropic_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],1, False, 'LRM'))
|
||||
def test_FaceIP_2D_anisotropic_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],2, False, 'LRM'))
|
||||
def test_FaceIP_3D_anisotropic_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],3, False, 'LRM'))
|
||||
def test_FaceIP_2D_tensor_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],3, False, 'LRM'))
|
||||
def test_FaceIP_3D_tensor_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],6, False, 'LRM'))
|
||||
def test_FaceIP_2D_float_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],0, False, 'Curv'))
|
||||
def test_FaceIP_3D_float_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],0, False, 'Curv'))
|
||||
def test_FaceIP_2D_isotropic_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],1, False, 'Curv'))
|
||||
def test_FaceIP_3D_isotropic_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],1, False, 'Curv'))
|
||||
def test_FaceIP_2D_anisotropic_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],2, False, 'Curv'))
|
||||
def test_FaceIP_3D_anisotropic_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],3, False, 'Curv'))
|
||||
def test_FaceIP_2D_tensor_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],3, False, 'Curv'))
|
||||
def test_FaceIP_3D_tensor_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],6, False, 'Curv'))
|
||||
|
||||
def test_FaceIP_2D_float_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],0, True, 'LRM'))
|
||||
def test_FaceIP_3D_float_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],0, True, 'LRM'))
|
||||
def test_FaceIP_2D_isotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],1, True, 'LRM'))
|
||||
def test_FaceIP_3D_isotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],1, True, 'LRM'))
|
||||
def test_FaceIP_2D_anisotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],2, True, 'LRM'))
|
||||
def test_FaceIP_3D_anisotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],3, True, 'LRM'))
|
||||
def test_FaceIP_2D_float_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],0, True, 'Curv'))
|
||||
def test_FaceIP_3D_float_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],0, True, 'Curv'))
|
||||
def test_FaceIP_2D_isotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],1, True, 'Curv'))
|
||||
def test_FaceIP_3D_isotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],1, True, 'Curv'))
|
||||
def test_FaceIP_2D_anisotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4],2, True, 'Curv'))
|
||||
def test_FaceIP_3D_anisotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestFace([10, 4, 5],3, True, 'Curv'))
|
||||
|
||||
def test_EdgeIP_2D_float_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],0, False, 'LRM'))
|
||||
def test_EdgeIP_3D_float_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],0, False, 'LRM'))
|
||||
def test_EdgeIP_2D_isotropic_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],1, False, 'LRM'))
|
||||
def test_EdgeIP_3D_isotropic_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],1, False, 'LRM'))
|
||||
def test_EdgeIP_2D_anisotropic_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],2, False, 'LRM'))
|
||||
def test_EdgeIP_3D_anisotropic_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],3, False, 'LRM'))
|
||||
def test_EdgeIP_2D_tensor_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],3, False, 'LRM'))
|
||||
def test_EdgeIP_3D_tensor_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],6, False, 'LRM'))
|
||||
def test_EdgeIP_2D_float_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],0, False, 'Curv'))
|
||||
def test_EdgeIP_3D_float_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],0, False, 'Curv'))
|
||||
def test_EdgeIP_2D_isotropic_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],1, False, 'Curv'))
|
||||
def test_EdgeIP_3D_isotropic_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],1, False, 'Curv'))
|
||||
def test_EdgeIP_2D_anisotropic_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],2, False, 'Curv'))
|
||||
def test_EdgeIP_3D_anisotropic_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],3, False, 'Curv'))
|
||||
def test_EdgeIP_2D_tensor_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],3, False, 'Curv'))
|
||||
def test_EdgeIP_3D_tensor_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],6, False, 'Curv'))
|
||||
|
||||
def test_EdgeIP_2D_float_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],0, True, 'LRM'))
|
||||
def test_EdgeIP_3D_float_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],0, True, 'LRM'))
|
||||
def test_EdgeIP_2D_isotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],1, True, 'LRM'))
|
||||
def test_EdgeIP_3D_isotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],1, True, 'LRM'))
|
||||
def test_EdgeIP_2D_anisotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],2, True, 'LRM'))
|
||||
def test_EdgeIP_3D_anisotropic_fast_LRM(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],3, True, 'LRM'))
|
||||
def test_EdgeIP_2D_float_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],0, True, 'Curv'))
|
||||
def test_EdgeIP_3D_float_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],0, True, 'Curv'))
|
||||
def test_EdgeIP_2D_isotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],1, True, 'Curv'))
|
||||
def test_EdgeIP_3D_isotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],1, True, 'Curv'))
|
||||
def test_EdgeIP_2D_anisotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4],2, True, 'Curv'))
|
||||
def test_EdgeIP_3D_anisotropic_fast_Curv(self):
|
||||
self.assertTrue(self.doTestEdge([10, 4, 5],3, True, 'Curv'))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ class MapTests(unittest.TestCase):
|
||||
self.assertTrue(maps.test())
|
||||
|
||||
|
||||
def test_transforms_logMap(self):
|
||||
# Note that log maps can be kinda finicky, so we are being explicit about the random seed.
|
||||
def test_transforms_logMap_reciprocalMap(self):
|
||||
# Note that log/reciprocal maps can be kinda finicky, so we are being explicit about the random seed.
|
||||
v2 = np.r_[ 0.40077291, 0.14410044, 0.58452314, 0.96323738, 0.01198519, 0.79754415]
|
||||
dv2 = np.r_[ 0.80653921, 0.13132446, 0.4901117, 0.03358737, 0.65473762, 0.44252488]
|
||||
v3 = np.r_[ 0.96084865, 0.34385186, 0.39430044, 0.81671285, 0.65929109, 0.2235217, 0.87897526, 0.5784033, 0.96876393, 0.63535864, 0.84130763, 0.22123854]
|
||||
@@ -41,6 +41,11 @@ class MapTests(unittest.TestCase):
|
||||
maps = Maps.LogMap(self.mesh3)
|
||||
self.assertTrue(maps.test(v3, dx=dv3))
|
||||
|
||||
maps = Maps.ReciprocalMap(self.mesh2)
|
||||
self.assertTrue(maps.test(v2, dx=dv2))
|
||||
maps = Maps.ReciprocalMap(self.mesh3)
|
||||
self.assertTrue(maps.test(v3, dx=dv3))
|
||||
|
||||
def test_Mesh2MeshMap(self):
|
||||
maps = Maps.Mesh2Mesh([self.mesh22, self.mesh2])
|
||||
self.assertTrue(maps.test())
|
||||
|
||||
@@ -4,7 +4,7 @@ from TestUtils import OrderTest
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
#TODO: 'randomTensorMesh'
|
||||
MESHTYPES = ['uniformTensorMesh', 'uniformLRM', 'rotateLRM']
|
||||
MESHTYPES = ['uniformTensorMesh', 'uniformCurv', 'rotateCurv']
|
||||
call2 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1])
|
||||
call3 = lambda fun, xyz: fun(xyz[:, 0], xyz[:, 1], xyz[:, 2])
|
||||
cart_row2 = lambda g, xfun, yfun: np.c_[call2(xfun, g), call2(yfun, g)]
|
||||
@@ -38,7 +38,7 @@ class TestCurl(OrderTest):
|
||||
curlE_ana = self.M.projectFaceVector(Fc)
|
||||
|
||||
curlE = self.M.edgeCurl.dot(E)
|
||||
if self._meshType == 'rotateLRM':
|
||||
if self._meshType == 'rotateCurv':
|
||||
# Really it is the integration we should be caring about:
|
||||
# So, let us look at the l2 norm.
|
||||
err = np.linalg.norm(self.M.area*(curlE - curlE_ana), 2)
|
||||
@@ -229,7 +229,7 @@ class TestFaceDiv3D(OrderTest):
|
||||
divF = self.M.faceDiv.dot(F)
|
||||
divF_ana = call3(sol, self.M.gridCC)
|
||||
|
||||
if self._meshType == 'rotateLRM':
|
||||
if self._meshType == 'rotateCurv':
|
||||
# Really it is the integration we should be caring about:
|
||||
# So, let us look at the l2 norm.
|
||||
err = np.linalg.norm(self.M.vol*(divF-divF_ana), 2)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from matutils import *
|
||||
from codeutils import *
|
||||
from meshutils import exampleLrmGrid, meshTensor, closestPoints, readUBCTensorMesh, writeUBCTensorMesh, writeUBCTensorModel, readVTRFile, writeVTRFile
|
||||
from lrmutils import volTetra, faceInfo, indexCube
|
||||
from curvutils import volTetra, faceInfo, indexCube
|
||||
from interputils import interpmat
|
||||
from ipythonutils import easyAnimate as animate
|
||||
from CounterUtils import *
|
||||
|
||||
@@ -58,9 +58,11 @@ def hook(obj, method, name=None, overwrite=False, silent=False):
|
||||
print 'Method '+name+' was not overwritten.'
|
||||
|
||||
|
||||
def setKwargs(obj, **kwargs):
|
||||
def setKwargs(obj, ignore=[], **kwargs):
|
||||
"""Sets key word arguments (kwargs) that are present in the object, throw an error if they don't exist."""
|
||||
for attr in kwargs:
|
||||
if attr in ignore:
|
||||
continue
|
||||
if hasattr(obj, attr):
|
||||
setattr(obj, attr, kwargs[attr])
|
||||
else:
|
||||
|
||||
+1
-1
@@ -16,7 +16,7 @@ import Inversion
|
||||
import Parallel
|
||||
import Tests
|
||||
|
||||
__version__ = '0.1.1'
|
||||
__version__ = '0.1.3'
|
||||
__author__ = 'Rowan Cockett'
|
||||
__license__ = 'MIT'
|
||||
__copyright__ = 'Copyright 2014 Rowan Cockett'
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
@@ -75,7 +75,7 @@ We multiply by square-root of volume on each side of the tensor conductivity to
|
||||
|
||||
.. math::
|
||||
\mathbf{J}_c = \mathbf{Q}_{(i)}\mathbf{J}_\text{TENSOR} \\
|
||||
\mathbf{J}_c = \mathbf{N}_{(i)}^{-1}\mathbf{Q}_{(i)}\mathbf{J}_\text{LRM}
|
||||
\mathbf{J}_c = \mathbf{N}_{(i)}^{-1}\mathbf{Q}_{(i)}\mathbf{J}_\text{Curv}
|
||||
|
||||
Here the \\\(i\\\) index refers to where we choose to approximate this integral, as discussed in the note above.
|
||||
We will approximate this integral by taking the fluxes clustered around every node of the cell, there are 8 combinations in 3D, and 4 in 2D. We will use a projection matrix \\\( \\mathbf{Q}_{(i)} \\\) to pick the appropriate fluxes. So, now that we have 8 approximations of this integral, we will just take the average. For the TensorMesh, this looks like:
|
||||
@@ -114,7 +114,7 @@ Here each \\( \\mathbf{P} \\in \\mathbb{R}^{(d*nC, nF)} \\\) is a combination of
|
||||
|
||||
.. math::
|
||||
|
||||
\mathbf{P}_{(i)} = \sqrt{ \frac{1}{2^d} \mathbf{I}^d \otimes \text{diag}(\mathbf{v})} \overbrace{\mathbf{N}_{(i)}^{-1}}^{\text{LRM only}} \mathbf{Q}_{(i)}
|
||||
\mathbf{P}_{(i)} = \sqrt{ \frac{1}{2^d} \mathbf{I}^d \otimes \text{diag}(\mathbf{v})} \overbrace{\mathbf{N}_{(i)}^{-1}}^{\text{Curv only}} \mathbf{Q}_{(i)}
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ the implementations.
|
||||
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.LogicallyRectMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
|
||||
rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
|
||||
|
||||
fig, axes = plt.subplots(1,3,figsize=(14,5))
|
||||
opts = {}
|
||||
@@ -38,7 +38,7 @@ the implementations.
|
||||
qM.plotGrid(ax=axes[1], **opts)
|
||||
axes[1].set_title('TreeMesh')
|
||||
rM.plotGrid(ax=axes[2], **opts)
|
||||
axes[2].set_title('LogicallyRectMesh')
|
||||
axes[2].set_title('CurvilinearMesh')
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ Tree Mesh
|
||||
:undoc-members:
|
||||
|
||||
|
||||
Logically Rectangular Mesh
|
||||
==========================
|
||||
Curvilinear Mesh
|
||||
================
|
||||
|
||||
.. automodule:: SimPEG.Mesh.LogicallyRectMesh
|
||||
.. automodule:: SimPEG.Mesh.Curvilinear
|
||||
:show-inheritance:
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
+2
-2
@@ -23,10 +23,10 @@ Solver Utilities
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
LRM Utilities
|
||||
Curv Utilities
|
||||
=============
|
||||
|
||||
.. automodule:: SimPEG.Utils.lrmutils
|
||||
.. automodule:: SimPEG.Utils.curvutils
|
||||
:members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
+2
-2
@@ -51,9 +51,9 @@ copyright = u'2013, SimPEG Developers'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1.1'
|
||||
version = '0.1.3'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1.1'
|
||||
release = '0.1.3'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
||||
@@ -33,7 +33,7 @@ with open("README.rst") as f:
|
||||
|
||||
setup(
|
||||
name = "SimPEG",
|
||||
version = "0.1.1",
|
||||
version = "0.1.3",
|
||||
packages = find_packages(),
|
||||
install_requires = ['numpy>=1.7',
|
||||
'scipy>=0.13'
|
||||
@@ -44,7 +44,7 @@ setup(
|
||||
long_description = LONG_DESCRIPTION,
|
||||
license = "MIT",
|
||||
keywords = "geophysics inverse problem",
|
||||
url = "http://simpeg.3ptscience.com/",
|
||||
url = "http://simpeg.xyz/",
|
||||
download_url = "http://github.com/simpeg/simpeg",
|
||||
classifiers=CLASSIFIERS,
|
||||
platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"],
|
||||
|
||||
Reference in New Issue
Block a user