Compare commits

..
Author SHA1 Message Date
Lindsey Heagy b0ca7959ab removed MT1d example from this pr 2016-02-16 09:46:22 -08:00
Lindsey Heagy 13c5857cda removed DC examples from this pr 2016-02-16 09:44:53 -08:00
Lindsey Heagy abcd1c9b7b fixed Mumps solver or LU solver opt 2016-02-16 09:40:53 -08:00
Lindsey e189ca4462 Update EM_FDEM_SusEffects.py
if mumps import fails use LU
2016-02-12 16:11:02 -08:00
Thibaut Astic 4cf5d49524 Ignoring non functioning examples 2016-02-12 15:48:48 -08:00
Thibaut Astic 88ef74ac38 MT_1D_analytic example 2016-02-12 15:40:48 -08:00
seogi_macbook 3a506b9051 Fix DC examples ... 2016-02-11 08:54:44 -08:00
seogi_macbook fa6bcd3ffa Minor changes 2016-02-11 00:10:25 -08:00
seogi_macbook 47895ef270 consistent file name 2016-02-10 23:58:48 -08:00
seogi_macbook 429d8b1191 Add EM_FDEM_SusEffects example 2016-02-10 23:45:19 -08:00
seogi_macbook 774d612c18 Merge branch 'master' of https://github.com/simpeg/simpeg into Examples
Conflicts:
	SimPEG/Examples/__init__.py
2016-02-10 23:38:51 -08:00
Lindsey 8ba9815137 Merge pull request #241 from simpeg/dev
Dev
2016-02-09 15:39:16 -08:00
Lindsey 994cba529b Merge pull request #227 from simpeg/dev
Dev
2016-02-05 17:55:13 -08:00
Lindsey Heagy 433457f649 docs and import for DC_PseudoSection_Simulation.rst 2016-02-03 20:12:55 -08:00
D Fournier 3eeb5dbd3c Remove dependency from Utils. Replace by internal function. 2016-02-03 20:03:05 -08:00
D Fournier df78f7b33a Branch off master
Add DC_Pseudo_Section example.
2016-02-03 14:35:03 -08:00
Lindsey 7c2d803dfe Merge pull request #225 from simpeg/patch/docsbadges
make travis badge look at master for docs
2016-02-02 09:54:43 -08:00
6 changed files with 225 additions and 65 deletions
+154
View File
@@ -0,0 +1,154 @@
from SimPEG import *
from SimPEG import EM
from scipy.constants import mu_0
def run(plotIt=True):
"""
EM: FDEM: Effects of susceptibility
===================================
When airborne freqeuncy domain EM (AFEM) survey is flown over
the earth including significantly susceptible bodies (magnetite-rich rocks),
negative data is often observed in the real part of the lowest frequency
(e.g. Dighem system 900 Hz). This phenomenon mostly based upon magnetization
occurs due to a susceptible body when the magnetic field is applied.
To clarify what is happening in the earth when we are exciting the earth with
a loop source in the frequency domain we run three forward modelling:
- F[:math:`\sigma`, :math:`\mu`]: Anomalous conductivity and susceptibility
- F[:math:`\sigma`, :math:`\mu_0`]: Anomalous conductivity
- F[:math:`\sigma_{air}`, :math:`\mu_0`]: primary field
We plot vector magnetic fields in the earth. For secondary fields we provide
F[:math:`\sigma`, :math:`\mu`]-F[:math:`\sigma`, :math:`\mu_0`]. Following
figure show both real and parts.
"""
# Generate Cylindrical mesh
cs, ncx, ncz, npad = 5, 25, 24, 20.
hx = [(cs,ncx), (cs,npad,1.3)]
hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)]
mesh = Mesh.CylMesh([hx,1,hz], '00C')
sighalf = 1e-3
sigma = np.ones(mesh.nC)*1e-8
sigmahomo = sigma.copy()
mu = np.ones(mesh.nC)*mu_0
sigma[mesh.gridCC[:,-1]<0.] = sighalf
blkind = np.logical_and(mesh.gridCC[:,0]<30., (mesh.gridCC[:,2]<0)&(mesh.gridCC[:,2]>-150)&(mesh.gridCC[:,2]<-50))
sigma[blkind] = 1e-1
mu[blkind] = mu_0*1.1
offset = 0.
frequency = np.r_[10., 100., 1000.]
rx0 = EM.FDEM.Rx(np.array([[8., 0., 30.]]), 'bzr')
rx1 = EM.FDEM.Rx(np.array([[8., 0., 30.]]), 'bzi')
srcLists = []
nfreq = frequency.size
for ifreq in range(nfreq):
src = EM.FDEM.Src.CircularLoop([rx0, rx1], frequency[ifreq], np.array([[0., 0., 30.]]), radius=5.)
srcLists.append(src)
survey = EM.FDEM.Survey(srcLists)
iMap = Maps.IdentityMap(nP=int(mesh.nC))
# Use PhysPropMap
maps = [('sigma', iMap), ('mu', iMap)]
prob = EM.FDEM.Problem_b(mesh, mapping=maps)
prob.Solver = MumpsSolver
survey.pair(prob)
m = np.r_[sigma, mu]
survey0 = EM.FDEM.Survey(srcLists)
prob0 = EM.FDEM.Problem_b(mesh, mapping=maps)
try:
from pymatsolver import MumpsSolver
prb.Solver = MumpsSolver
except ImportError, e:
prb.Solver = SolverLU
survey0.pair(prob0)
m = np.r_[sigma, mu]
m0 = np.r_[sigma, np.ones(mesh.nC)*mu_0]
m00 = np.r_[np.ones(mesh.nC)*1e-8, np.ones(mesh.nC)*mu_0]
# Anomalous conductivity and susceptibility
F = prob.fields(m)
# Only anomalous conductivity
F0 = prob.fields(m0)
# Primary field
F00 = prob.fields(m00)
if plotIt:
import matplotlib.pyplot as plt
def vizfields(ifreq=0, primsec="secondary",realimag="real"):
titles = ["F[$\sigma$, $\mu$]", "F[$\sigma$, $\mu_0$]", "F[$\sigma$, $\mu$]-F[$\sigma$, $\mu_0$]"]
actind = np.logical_and(mesh.gridCC[:,0]<200., (mesh.gridCC[:,2]>-400)&(mesh.gridCC[:,2]<200))
if primsec=="secondary":
bCCprim = (mesh.aveF2CCV*F00[:,'b'][:,ifreq]).reshape(mesh.nC, 2, order='F')
bCC = (mesh.aveF2CCV*F[:,'b'][:,ifreq]).reshape(mesh.nC, 2, order='F')-bCCprim
bCC0 = (mesh.aveF2CCV*F0[:,'b'][:,ifreq]).reshape(mesh.nC, 2, order='F')-bCCprim
elif primsec=="primary":
bCC = (mesh.aveF2CCV*F[:,'b'][:,ifreq]).reshape(mesh.nC, 2, order='F')
bCC0 = (mesh.aveF2CCV*F0[:,'b'][:,ifreq]).reshape(mesh.nC, 2, order='F')
XYZ = mesh.gridCC[actind,:]
X = XYZ[:,0].reshape((31,43), order='F')
Z = XYZ[:,2].reshape((31,43), order='F')
bx = bCC[actind,0].reshape((31,43), order='F')
bz = bCC[actind,1].reshape((31,43), order='F')
bx0 = bCC0[actind,0].reshape((31,43), order='F')
bz0 = bCC0[actind,1].reshape((31,43), order='F')
bxsec = (bCC[actind,0]-bCC0[actind,0]).reshape((31,43), order='F')
bzsec = (bCC[actind,1]-bCC0[actind,1]).reshape((31,43), order='F')
absbreal = np.sqrt(bx.real**2+bz.real**2)
absbimag = np.sqrt(bx.imag**2+bz.imag**2)
absb0real = np.sqrt(bx0.real**2+bz0.real**2)
absb0imag = np.sqrt(bx0.imag**2+bz0.imag**2)
absbrealsec = np.sqrt(bxsec.real**2+bzsec.real**2)
absbimagsec = np.sqrt(bxsec.imag**2+bzsec.imag**2)
fig = plt.figure(figsize=(15,5))
ax1 = plt.subplot(131)
ax2 = plt.subplot(132)
ax3 = plt.subplot(133)
typefield="real"
scale=20
if realimag=="real":
ax1.contourf(X, Z,np.log10(absbreal), 100)
ax1.quiver(X, Z,bx.real/absbreal,bz.real/absbreal,scale=scale,width=0.005, alpha = 0.5)
ax2.contourf(X, Z,np.log10(absb0real), 100)
ax2.quiver(X, Z,bx0.real/absb0real,bz0.real/absb0real,scale=scale,width=0.005, alpha = 0.5)
ax3.contourf(X, Z,np.log10(absbrealsec), 100)
ax3.quiver(X, Z,bxsec.real/absbrealsec,bzsec.real/absbrealsec,scale=scale,width=0.005, alpha = 0.5)
elif realimag=="imag":
ax1.contourf(X, Z,np.log10(absbimag), 100)
ax1.quiver(X, Z,bx.imag/absbimag,bz.imag/absbimag,scale=scale,width=0.005, alpha = 0.5)
ax2.contourf(X, Z,np.log10(absb0imag), 100)
ax2.quiver(X, Z,bx0.imag/absb0imag,bz0.imag/absb0imag,scale=scale,width=0.005, alpha = 0.5)
ax3.contourf(X, Z,np.log10(absbimagsec), 100)
ax3.quiver(X, Z,bxsec.imag/absbimagsec,bzsec.imag/absbimagsec,scale=scale,width=0.005, alpha = 0.5)
ax = [ax1, ax2, ax3]
ax3.text(30, 50, ("Frequency=%5.2f Hz")%(frequency[ifreq]), color="k", fontsize=18)
ax2.text(30, 50, primsec, color="k", fontsize=18)
ax1.text(30, 50, realimag, color="k", fontsize=18)
for i, axtemp in enumerate(ax):
axtemp.plot(np.r_[0, 29.75], np.r_[-50, -50], 'w', lw=3)
axtemp.plot(np.r_[29.5, 29.5], np.r_[-50, -142.5], 'w', lw=3)
axtemp.plot(np.r_[0, 29.5], np.r_[-142.5, -142.5], 'w', lw=3)
axtemp.plot(np.r_[0, 100.], np.r_[0, 0], 'w', lw=3)
axtemp.set_ylim(-200, 100.)
axtemp.set_xlim(10, 100.)
axtemp.set_title(titles[i])
plt.show()
return fig, ax
fig1, ax1 = vizfields(1, primsec="primary", realimag="real")
fig2, ax2 = vizfields(1, primsec="secondary", realimag="real")
fig4, ax4 = vizfields(1, primsec="secondary", realimag="imag")
if __name__ == '__main__':
run()
+3 -1
View File
@@ -3,6 +3,7 @@
##### AUTOIMPORTS #####
import EM_FDEM_1D_Inversion
import EM_FDEM_Analytic_MagDipoleWholespace
import EM_FDEM_SusEffects
import EM_TDEM_1D_Inversion
import FLOW_Richards_1D_Celia1990
import Forward_BasicDirectCurrent
@@ -14,8 +15,9 @@ import Mesh_QuadTree_Creation
import Mesh_QuadTree_FaceDiv
import Mesh_QuadTree_HangingNodes
import Mesh_Tensor_Creation
import MT_1D_analytic_nlayer_Earth
__examples__ = ["EM_FDEM_1D_Inversion", "EM_FDEM_Analytic_MagDipoleWholespace", "EM_TDEM_1D_Inversion", "FLOW_Richards_1D_Celia1990", "Forward_BasicDirectCurrent", "Inversion_Linear", "Mesh_Basic_PlotImage", "Mesh_Basic_Types", "Mesh_Operators_CahnHilliard", "Mesh_QuadTree_Creation", "Mesh_QuadTree_FaceDiv", "Mesh_QuadTree_HangingNodes", "Mesh_Tensor_Creation"]
__examples__ = ["EM_FDEM_1D_Inversion", "EM_FDEM_Analytic_MagDipoleWholespace", "EM_FDEM_SusEffects", "EM_TDEM_1D_Inversion", "FLOW_Richards_1D_Celia1990", "Forward_BasicDirectCurrent", "Inversion_Linear", "Mesh_Basic_PlotImage", "Mesh_Basic_Types", "Mesh_Operators_CahnHilliard", "Mesh_QuadTree_Creation", "Mesh_QuadTree_FaceDiv", "Mesh_QuadTree_HangingNodes", "Mesh_Tensor_Creation", "MT_1D_analytic_nlayer_Earth"]
##### AUTOIMPORTS #####
+14
View File
@@ -990,4 +990,18 @@ class ProjectedGNCG(BFGS, Minimize, Remember):
cgFlag = 1
# End CG Iterations
# Take a gradient step on the active cells if exist
if temp != self.xc.size:
rhs_a = (Active) * -self.g
dm_i = max( abs( delx ) )
dm_a = max( abs(rhs_a) )
delx = delx + rhs_a * dm_i / dm_a /10.
# Only keep gradients going in the right direction on the active set
indx = ((self.xc<=self.lower) & (delx < 0)) | ((self.xc>=self.upper) & (delx > 0))
delx[indx] = 0.
return delx
+13 -50
View File
@@ -34,18 +34,6 @@ class Property(object):
setattr(self, '_%sMap'%prop.name, val)
return property(fget=fget, fset=fset, doc=prop.doc)
def _getDefaultProperty(self):
prop = self
def fget(self):
return getattr(self, '_%sDefault'%prop.name, None)
def fset(self, val):
if prop.propertyLink is not None:
linkName, linkMap = prop.propertyLink
assert getattr(self, '%sDefault'%linkName, None) is None, 'Cannot set both sides of a linked property.'
assert isinstance(val, np.ndarray) or np.isscalar(val), 'Default must be a scalar or a numpy array.'
setattr(self, '_%sDefault'%prop.name, val)
return property(fget=fget, fset=fset, doc=prop.doc)
def _getIndexProperty(self):
prop = self
def fget(self):
@@ -59,17 +47,12 @@ class Property(object):
def fget(self):
mapping = getattr(self, '%sMap'%prop.name)
if mapping is None and prop.propertyLink is None:
return getattr(self, '%sDefault'%prop.name)
return prop.defaultVal
if mapping is None and prop.propertyLink is not None:
linkName, linkMapClass = prop.propertyLink
linkMap = linkMapClass(None)
# *
print linkName, getattr(self.propMap, '_%sDefault'%linkName, None)
if getattr(self, '%sMap'%linkName, None) is None and getattr(self.propMap, '_%sDefault'%linkName, None) is not None:
# We have a default
return linkMap * getattr(self, '%sDefault'%linkName, None)
elif getattr(self, '%sMap'%linkName, None) is None:
if getattr(self, '%sMap'%linkName, None) is None:
return prop.defaultVal
m = getattr(self, '%s'%linkName)
return linkMap * m
@@ -127,12 +110,6 @@ class Property(object):
return getattr(self.propMap, '_%sMap'%prop.name, None)
return property(fget=fget)
def _getModelDefaultProperty(self):
prop = self
def fget(self):
return getattr(self.propMap, '_%sDefault'%prop.name, prop.defaultVal)
return property(fget=fget)
class PropModel(object):
@@ -173,9 +150,8 @@ class _PropMapMetaClass(type):
for attr in keys:
if isinstance(attrs[attr], Property):
attrs[attr].name = attr
attrs[attr + 'Map' ] = attrs[attr]._getMapProperty()
attrs[attr + 'Default'] = attrs[attr]._getDefaultProperty()
attrs[attr + 'Index' ] = attrs[attr]._getIndexProperty()
attrs[attr + 'Map' ] = attrs[attr]._getMapProperty()
attrs[attr + 'Index'] = attrs[attr]._getIndexProperty()
_properties[attr] = attrs[attr]
attrs.pop(attr)
@@ -205,12 +181,11 @@ class _PropMapMetaClass(type):
for attr in _properties:
prop = _properties[attr]
attrs[attr ] = prop._getProperty()
attrs[attr + 'Map' ] = prop._getModelMapProperty()
attrs[attr + 'Default'] = prop._getModelDefaultProperty()
attrs[attr + 'Proj' ] = prop._getModelProjProperty()
attrs[attr + 'Model' ] = prop._getModelProperty()
attrs[attr + 'Deriv' ] = prop._getModelDerivProperty()
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)
@@ -223,8 +198,8 @@ class PropMap(object):
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', 'defaults'] for k in mappings]), 'Dict must only have properties "maps", "slices" and "defaults"'
self.setup(mappings['maps'], slices=mappings.get('slices',{}), defaults=mappings.get('defaults',{}))
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):
@@ -233,7 +208,7 @@ class PropMap(object):
raise Exception('mappings must be a dict, a mapping, or a list of tuples.')
def setup(self, maps, slices=None, defaults=None):
def setup(self, maps, slices=None):
"""
Sets up the maps and slices for the PropertyMap
@@ -256,13 +231,6 @@ class PropMap(object):
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'
if defaults is None:
defaults = dict()
else:
assert np.all([
s in self._properties and
(np.isscalar(defaults[s]) or isinstance(defaults[s], np.ndarray))
for s in defaults]), 'Defaults must be for each property'
self.clearMaps()
@@ -271,12 +239,7 @@ class PropMap(object):
setattr(self, '%sMap'%name, mapping)
setattr(self, '%sIndex'%name, slices.get(name, slice(nP, nP + mapping.nP)))
nP += mapping.nP
self.nP = nP
for key in defaults:
setattr(self, '%sDefault'%key, defaults[key])
self.nP = nP
@property
def defaultInvProp(self):
+41
View File
@@ -0,0 +1,41 @@
.. _examples_EM_FDEM_SusEffects:
.. --------------------------------- ..
.. ..
.. THIS FILE IS AUTO GENEREATED ..
.. ..
.. SimPEG/Examples/__init__.py ..
.. ..
.. --------------------------------- ..
EM: FDEM: Effects of susceptibility
===================================
When airborne freqeuncy domain EM (AFEM) survey is flown over
the earth including significantly susceptible bodies (magnetite-rich rocks),
negative data is often observed in the real part of the lowest frequency
(e.g. Dighem system 900 Hz). This phenomenon mostly based upon magnetization
occurs due to a susceptible body when the magnetic field is applied.
To clarify what is happening in the earth when we are exciting the earth with
a loop source in the frequency domain we run three forward modelling:
- F[:math:`\sigma`, :math:`\mu`]: Anomalous conductivity and susceptibility
- F[:math:`\sigma`, :math:`\mu_0`]: Anomalous conductivity
- F[:math:`\sigma_{air}`, :math:`\mu_0`]: primary field
We plot vector magnetic fields in the earth. For secondary fields we provide
F[:math:`\sigma`, :math:`\mu`]-F[:math:`\sigma`, :math:`\mu_0`]. Following
figure show both real and parts.
.. plot::
from SimPEG import Examples
Examples.EM_FDEM_SusEffects.run()
.. literalinclude:: ../../SimPEG/Examples/EM_FDEM_SusEffects.py
:language: python
:linenos:
-14
View File
@@ -56,22 +56,8 @@ class TestPropMaps(unittest.TestCase):
assert np.all(m.sigma == np.exp(np.r_[1.,2,3]))
assert m.sigmaDeriv is not None
assert m.mu == mu_0
assert m.nP == 3
def test_defaultOverride(self):
expMap = Maps.ExpMap(Mesh.TensorMesh((3,)))
PM = MyReciprocalPropMap({'maps':[('sigma', expMap)], 'defaults':{'mu':mu_0*2}})
self.assertRaises(Exception, MyReciprocalPropMap, {'maps':[('sigma', expMap)], 'defaults':{'mu':mu_0*2, 'mui':5}}) # Cannot set both sides of the default
m = PM(np.r_[1.,2,3])
assert np.all(m.sigmaModel == np.r_[1,2,3])
self.assertEqual(m.mu, mu_0 * 2)
# self.assertEqual(m.mui, 1/(mu_0 * 2))
def test_slices(self):
expMap = Maps.ExpMap(Mesh.TensorMesh((3,)))
PM = MyPropMap({'maps':[('sigma', expMap)], 'slices':{'sigma':[2,1,0]}})