Compare commits

..
100 Commits
Author SHA1 Message Date
gitea 714afa860f misc fixes
- 2to3 on setup.py to allow python 3 import
- removed uneeded circular import in Maps.py
- added missing old_div o mathutils
2016-07-21 14:20:37 +08:00
Brendan Smithyman f7a70aa6a7 Possibly deal with a good chunk of the old_divs 2016-07-17 16:02:43 -05:00
Brendan Smithyman 7189ec5b2f Test Python3. 2016-07-16 14:37:45 -05:00
Brendan Smithyman 4c2a61bf54 Fix deps. 2016-07-16 14:35:56 -05:00
Brendan Smithyman ca8d8f8c2d Futurize 1, futurize 2, pasteurize. 2016-07-16 14:17:02 -05:00
Lindsey Heagy 362975d2bd Merge pull request #359 from simpeg/dev
Dev
2016-07-15 15:26:39 -05:00
Lindsey Heagy cf34415ae8 Merge pull request #358 from simpeg/feat/codecov
Feat/codecov
2016-07-14 08:51:57 -06:00
Lindsey Heagy 09ec5621ae remove coveralls 2016-07-13 19:46:27 -07:00
Lindsey Heagy 4e583fc566 fix indentation level 2016-07-13 13:40:38 -07:00
Lindsey Heagy ea62998250 use codecov.io 2016-07-13 12:15:15 -07:00
SEOGI KANG 4796b0f91f Merge pull request #357 from simpeg/analytics
Analytics
2016-06-30 00:25:28 -07:00
seogi_macbook 52b25e2dc5 Merge branch 'dev' of https://github.com/simpeg/simpeg into analytics 2016-06-30 00:23:12 -07:00
seogi_macbook a289b656cd Fixes for kwargs variables in FDEMDipolarfields.py 2016-06-29 13:09:11 -07:00
Lindsey Heagy 334cd8e454 Bump version: 0.1.11 → 0.1.12 2016-06-29 09:49:29 -07:00
Lindsey Heagy ecbdd90f63 Merge pull request #354 from simpeg/dev
Two new examples.
2016-06-29 09:46:33 -07:00
dfournier 394dc9106a Merge pull request #332 from simpeg/ref/regularization
Automate the epsilon picking based on percentile of model values for …
2016-06-29 08:39:29 -07:00
seogi_macbook eda2394411 fix bug for omega. 2016-06-27 13:04:30 -07:00
Rowan Cockett 3deca9ed77 Merge pull request #351 from simpeg/example/mesh2mesh
Mesh2Mesh and Combo Map examples.
2016-06-26 21:22:28 -06:00
Rowan Cockett ba173674ec Mesh2Mesh and Combo Map examples.
Also fixed plotting codes to show the plots by default.
2016-06-26 17:07:07 -06:00
Rowan Cockett 303da372aa Merged branch master into dev 2016-06-26 16:31:24 -06:00
Rowan Cockett 6d6e7fc8bd Merge pull request #350 from simpeg/fix/docs-images
Update index.rst
2016-06-26 16:30:29 -06:00
Rowan Cockett 8ed3ec18fa Update README.rst 2016-06-26 16:29:20 -06:00
Rowan Cockett 3960cfc313 Update index.rst 2016-06-26 16:17:30 -06:00
Rowan Cockett 2eba0b841f Merge pull request #338 from simpeg/dev
Dev
2016-06-26 14:01:03 -06:00
sgkang c79bb998cb Merge pull request #348 from simpeg/analytics
fix minor bugs in analytics (just for binder deploy)
2016-06-23 14:14:29 -07:00
seogi_macbook 0763925743 fix minor bugs in analytics 2016-06-23 14:12:49 -07:00
sgkang 1a0b81a206 Merge pull request #341 from simpeg/analytics
Analytics
2016-06-23 11:33:33 -07:00
seogi_macbook 8b44f8d96b change FDEM_fields.py to FDEMDipolarfield.py 2016-06-23 10:14:13 -07:00
seogi_macbook 2bfd01ed7c Merge branch 'dev' of https://github.com/simpeg/simpeg into analytics 2016-06-23 10:09:56 -07:00
seogi_macbook e1ba80883d Incorporate Lindsey's suggestoins 2016-06-23 09:10:50 -07:00
Rowan Cockett a54713f546 Change to NotImplementedError. 2016-06-22 11:32:54 -06:00
Lindsey Heagy ef382aed85 Merge branch 'master' into dev 2016-06-21 18:43:28 -06:00
seogi_macbook 1b33804e5a Merge branch 'dev' of https://github.com/simpeg/simpeg into analytics 2016-06-21 11:15:23 -07:00
seogi_macbook c161c5eab2 Merge branch 'master' of https://github.com/simpeg/simpeg into analytics 2016-06-21 11:14:56 -07:00
micmitch f0944362c8 Silly mistake... needed zero arrays instead of scalars. 2016-06-14 15:22:36 -07:00
micmitch e815ddaec7 Removed d typos from the end of function names. 2016-06-14 15:15:53 -07:00
Lindsey 64b0b4561f Merge pull request #337 from simpeg/feat/docs-gae-travis-deploy
Feat/docs gae travis deploy
2016-06-13 19:16:22 -06:00
micmitch b9d30af4a8 Changed \sigma to \hat{\sigma} = \sigma + i \omega \epsilon in the E field calculations. 2016-06-13 17:47:46 -07:00
micmitch 093f441331 Added functions to split electric field into "galvanic" and "inductive" portions. 2016-06-13 17:35:52 -07:00
seogi_macbook 5e3c1da8e2 add place holder for galvanic and inductive electric fields... 2016-06-13 16:41:59 -07:00
seogi_macbook a3a5c86008 Fix couple bugs in FDEM analytics 2016-06-11 21:58:03 +02:00
Lindsey Heagy 7a82f57367 - doc the simple regularization, sparse regularization and regularization mesh
- typo fix in MT_3D_Forward example - Solver
- use EM.Static.DC for DC example
2016-06-11 08:16:22 -07:00
Lindsey Heagy 845c3c10ab version on travis commit 2016-06-11 07:48:24 -07:00
Lindsey Heagy c4d86b4a29 Merge branch 'dev' into feat/docs-gae-travis-deploy 2016-06-11 07:14:00 -07:00
Lindsey Heagy 3fc855f3c9 only push on master 2016-06-10 20:50:41 -07:00
Lindsey Heagy fea508a507 fix path to app.yaml 2016-06-10 19:39:02 -07:00
Lindsey Heagy 5ca52cf49f linting travis deploy of docs 2016-06-10 19:14:24 -07:00
Lindsey Heagy 7a06453c42 editing travis deploy 2016-06-10 18:54:31 -07:00
Lindsey Heagy 291da78b97 try deploying only from docs branch 2016-06-10 15:16:56 -07:00
D Fournier ef12a3674a Automate the epsilon picking based on percentile of model values for DEFAULT mode. Fix example.
Fix bug with Maps using array of values
2016-06-06 12:28:01 -07:00
Lindsey Heagy 504592c8de travis typo fixes 2016-06-01 08:12:21 -07:00
Lindsey Heagy 75647f8fc3 first pass at gae deploy 2016-06-01 00:00:27 -07:00
Lindsey Heagy e3462666bd working on travis decrypt 2016-05-31 23:27:32 -07:00
Lindsey Heagy fb37bf0fe2 move unpacking of credentials to after success, point credentials to docs folder 2016-05-31 23:15:50 -07:00
Lindsey Heagy b023adbb33 add encrypted credentials for gae site and decrypt on travis 2016-05-31 23:03:55 -07:00
Lindsey Heagy 279bd49b4c Bump version: 0.1.10 → 0.1.11 2016-05-31 15:38:05 -07:00
Lindsey Heagy 3398d5ab4d use templates in conf.py, add google analytics to docs 2016-05-31 15:33:19 -07:00
Lindsey 3e26bb7de9 Merge pull request #277 from simpeg/dev
Dev
2016-05-31 15:11:29 -07:00
Lindsey Heagy 01e19e4227 start of gae site 2016-05-30 22:01:15 -07:00
Lindsey Heagy 9fbdaaf0a5 fix typo in examples path 2016-05-30 21:12:31 -07:00
Lindsey Heagy 2a159e20b9 update docs for examples to point to the correct path 2016-05-30 20:34:10 -07:00
Lindsey Heagy 5e8d3fbc78 organizing the docs - put the content in a content folder. put the SimPEG core api docs in core_api 2016-05-30 17:06:29 -07:00
Lindsey Heagy 414418a996 Merge branch 'dev' into feat/docs-deploy
# Conflicts:
#	SimPEG/Mesh/View.py
2016-05-30 15:56:24 -07:00
Rowan Cockett 40f0874dfb Doc testing, I think that is most of them! 2016-05-29 22:18:22 -07:00
Rowan Cockett 231e6dbc93 Suppress image warning. 2016-05-29 19:22:15 -07:00
Rowan Cockett 18f98b2ecd Merge branch 'docs' of https://github.com/simpeg/simpeg into feat/docs-deploy
# Conflicts:
#	SimPEG/Utils/meshutils.py
#	docs/api_Utils.rst
#	docs/conf.py
#	docs/flow/index.rst
2016-05-29 19:18:36 -07:00
Rowan Cockett bc073e49b5 Updates to docs errors. 2016-05-29 18:57:38 -07:00
Rowan Cockett a131383dae Correct solver location. 2016-05-29 18:35:41 -07:00
Rowan Cockett ad4a0240d1 Remove Vertical1DMap from tests. 2016-05-29 18:34:17 -07:00
Rowan Cockett 74f5395573 Surject1D updates. 2016-05-29 18:25:42 -07:00
Rowan Cockett 6f7a0b1279 Rename Vertical1DMap to SurjectVertical1D due to depreciation. 2016-05-29 18:14:42 -07:00
Rowan Cockett e2bb9c8d8e rename flow example. 2016-05-29 18:12:52 -07:00
Rowan Cockett de693adaa7 Minor updates to get it 'working'
There still seems to be a problem with this example:

	- The line search breaks.
	- The plots are not informative.
	- There are a lot of errors in the structured array codes.
2016-05-29 18:04:09 -07:00
Rowan Cockett fc07993006 Spacings in functions. 2016-05-29 18:03:03 -07:00
Rowan Cockett 12a12c7b5a updates to FDEM docs. 2016-05-29 17:51:41 -07:00
Rowan Cockett 0b4215f33e Add DC and IP docs. 2016-05-29 17:45:49 -07:00
Rowan Cockett 5e2a8232a3 Minor updates to titles in examples. 2016-05-29 17:21:37 -07:00
Rowan Cockett feba384911 Add solver parameter to the Casing example. 2016-05-29 17:08:11 -07:00
Rowan Cockett 4844b7230a TOC updates for docs index. 2016-05-29 17:05:42 -07:00
micmitch 1960b52dfd First stab at analytic functions for the fields from a harmonic electric dipole source. Not sure about the exception that I try to throw if multiple frequencies and multiple evaluation locations are both specified. 2016-05-27 14:56:48 -07:00
seogi_macbook 28d67e3112 Start of ED !! 2016-05-27 11:26:47 -07:00
Lindsey Heagy 756b738ef2 Merge branch 'dev' into docs 2016-04-05 17:47:17 -07:00
Lindsey Heagy 021e7c794c Merge branch 'master' into docs
# Conflicts:
#	SimPEG/Mesh/TensorMesh.py
2016-03-29 22:53:16 -07:00
Lindsey Heagy b5b70390cb Merge branch 'dev' into docs 2016-03-06 21:50:27 -08:00
Lindsey Heagy 6acaa81faf fixed merge conflicts in FDEM docs that I missed 2016-02-09 09:03:20 -08:00
Lindsey Heagy 312b5d79c5 resolved merge conflicts in TensorMesh 2016-02-09 08:53:01 -08:00
Lindsey Heagy 999a37547e Merge branch 'dev' into docs
# Conflicts:
#	.travis.yml
#	SimPEG/EM/FDEM/FDEM.py
#	SimPEG/Mesh/TensorMesh.py
2016-02-09 08:32:41 -08:00
Lindsey Heagy cbe8758465 corrected scipy.sparse.csr_matrix, move size descriptions to :return: instead of :type: 2016-02-01 08:22:00 -08:00
Lindsey Heagy 6b359f49b5 docs clean-up (using autoclass is more stable than automodule) 2016-01-31 15:21:46 -08:00
Lindsey Heagy 2254eedbac indentations clean up in FDEM.py 2016-01-31 13:54:39 -08:00
Lindsey Heagy 012d2cadf1 use intersphinx mapping to get numpy, scipy, matplotlib, python inventories 2016-01-31 13:54:24 -08:00
Lindsey Heagy 841ba61006 clean up the html build 2016-01-31 13:22:36 -08:00
Lindsey Heagy 2874e204ee exclude _static from warnings 2016-01-31 12:52:42 -08:00
Lindsey Heagy adca273565 ignore nonlocal images in sphinx build 2016-01-31 12:46:24 -08:00
Lindsey Heagy d9d6f70958 better description of paths in test_docs 2016-01-31 12:45:51 -08:00
Lindsey Heagy f4ef767764 seperate out docs test so it runs independently (not on every test) 2016-01-31 12:08:29 -08:00
Lindsey Heagy e314bdb740 add sphinx to travis conda install 2016-01-31 11:06:47 -08:00
Lindsey Heagy e005ed8f5f use cd to get into docs directories for testing 2016-01-31 10:51:55 -08:00
Lindsey Heagy ac2e38e89d test docs first 2016-01-31 10:47:00 -08:00
Lindsey Heagy ade37fb493 add travis to docs. nit-picky testing on html, latex, link check 2016-01-31 09:51:57 -08:00
282 changed files with 5137 additions and 3510 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
[bumpversion] [bumpversion]
current_version = 0.1.10 current_version = 0.1.12
files = setup.py SimPEG/__init__.py docs/conf.py files = setup.py SimPEG/__init__.py docs/conf.py
+2
View File
@@ -39,3 +39,5 @@ nosetests.xml
*.sublime-workspace *.sublime-workspace
docs/_build/ docs/_build/
Makefile Makefile
docs/warnings.txt
.DS_Store
+28 -5
View File
@@ -1,6 +1,7 @@
language: python language: python
python: python:
- 2.7 - 2.7
- 3.4
sudo: false sudo: false
@@ -24,18 +25,25 @@ env:
- TEST_DIR=tests/examples - TEST_DIR=tests/examples
- TEST_DIR=tests/em/fdem/inverse/adjoint - TEST_DIR=tests/em/fdem/inverse/adjoint
- TEST_DIR=tests/em/fdem/forward - TEST_DIR=tests/em/fdem/forward
- TEST_DIR=tests/docs;
GAE_PYTHONPATH=${HOME}/.cache/google_appengine;
PATH=$PATH:${HOME}/google-cloud-sdk/bin;
PYTHONPATH=${PYTHONPATH}:${GAE_PYTHONPATH};
CLOUDSDK_CORE_DISABLE_PROMPTS=1
# Setup anaconda # Setup anaconda
before_install: before_install:
- if [ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]; then wget http://repo.continuum.io/miniconda/Miniconda-3.8.3-Linux-x86_64.sh -O miniconda.sh; else wget http://repo.continuum.io/miniconda/Miniconda3-3.8.3-Linux-x86_64.sh -O miniconda.sh; fi # Install packages
- if [ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]; then wget http://repo.continuum.io/miniconda/Miniconda-3.8.3-Linux-x86_64.sh
-O miniconda.sh; else wget http://repo.continuum.io/miniconda/Miniconda3-3.8.3-Linux-x86_64.sh
-O miniconda.sh; fi
- chmod +x miniconda.sh - chmod +x miniconda.sh
- ./miniconda.sh -b - ./miniconda.sh -b
- export PATH=/home/travis/anaconda/bin:/home/travis/miniconda/bin:$PATH - export PATH=/home/travis/anaconda/bin:/home/travis/anaconda3/bin:/home/travis/miniconda/bin:/home/travis/miniconda3/bin:$PATH
- conda update --yes conda - conda update --yes conda
# Install packages
install: install:
- conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython ipywidgets nose vtk - conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython nose vtk sphinx
- pip install nose-cov python-coveralls - pip install nose-cov python-coveralls
- git clone https://github.com/rowanc1/pymatsolver.git - git clone https://github.com/rowanc1/pymatsolver.git
@@ -46,11 +54,26 @@ install:
# Run test # Run test
script: script:
# test docs
- nosetests $TEST_DIR --with-cov --cov SimPEG --cov-config .coveragerc -v -s - nosetests $TEST_DIR --with-cov --cov SimPEG --cov-config .coveragerc -v -s
# Calculate coverage # Calculate coverage
after_success: after_success:
- coveralls --config_file .coveragerc - bash <(curl -s https://codecov.io/bash)
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then
if [ ${TEST_DIR} == "tests/docs" ]; then
python scripts/fetch_gae_sdk.py $(dirname "${GAE_PYTHONPATH}");
openssl aes-256-cbc -K $encrypted_93066031461c_key -iv $encrypted_93066031461c_iv
-in docs/credentials.tar.gz.enc -out credentials.tar.gz -d ;
if [ ! -d ${HOME}/google-cloud-sdk ]; then curl https://sdk.cloud.google.com | bash; fi ;
tar -xzf credentials.tar.gz ;
gcloud auth activate-service-account --key-file client-secret.json ;
gcloud config set project simpegdocs;
gcloud -q components update gae-python;
gcloud -q preview app deploy ./docs/app.yaml --version ${TRAVIS_COMMIT} --promote;
fi;
fi
notifications: notifications:
email: email:
+6 -2
View File
@@ -1,4 +1,4 @@
.. image:: https://raw.github.com/simpeg/simpeg/master/docs/simpeg-logo.png .. image:: https://raw.github.com/simpeg/simpeg/master/docs/images/simpeg-logo.png
:alt: SimPEG Logo :alt: SimPEG Logo
====== ======
@@ -28,7 +28,11 @@ SimPEG
.. image:: http://img.shields.io/badge/GITTER-JOIN_CHAT-brightgreen.svg?style=flat-square .. image:: http://img.shields.io/badge/GITTER-JOIN_CHAT-brightgreen.svg?style=flat-square
:alt: gitter chat room at https://gitter.im/simpeg/simpeg :alt: gitter chat room at https://gitter.im/simpeg/simpeg
:target: https://gitter.im/simpeg/simpeg :target: https://gitter.im/simpeg/simpeg
.. image:: https://codecov.io/gh/simpeg/simpeg/branch/master/graph/badge.svg
  :target: https://codecov.io/gh/simpeg/simpeg
Simulation and Parameter Estimation in Geophysics - A python package for simulation and gradient based parameter estimation in the context of geophysical applications. Simulation and Parameter Estimation in Geophysics - A python package for simulation and gradient based parameter estimation in the context of geophysical applications.
The vision is to create a package for finite volume simulation with applications to geophysical imaging and subsurface flow. To enable the understanding of the many different components, this package has the following features: The vision is to create a package for finite volume simulation with applications to geophysical imaging and subsurface flow. To enable the understanding of the many different components, this package has the following features:
+11 -3
View File
@@ -1,3 +1,11 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from builtins import super
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
class FieldsDC_CC(Problem.Fields): class FieldsDC_CC(Problem.Fields):
@@ -61,7 +69,7 @@ class SrcDipole(Survey.BaseSrc):
pts = [self.loc[0], self.loc[1]] pts = [self.loc[0], self.loc[1]]
inds = Utils.closestPoints(prob.mesh, pts) inds = Utils.closestPoints(prob.mesh, pts)
q = np.zeros(prob.mesh.nC) q = np.zeros(prob.mesh.nC)
q[inds] = - self.current * ( np.r_[1., -1.] / prob.mesh.vol[inds] ) q[inds] = - self.current * (np.r_[1., -1.] / prob.mesh.vol[inds])
# self._rhsDict[mesh] = q # self._rhsDict[mesh] = q
# return self._rhsDict[mesh] # return self._rhsDict[mesh]
return q return q
@@ -162,8 +170,8 @@ class ProblemDC_CC(Problem.BaseProblem):
""" """
Makes the matrix A(m) for the DC resistivity problem. Makes the matrix A(m) for the DC resistivity problem.
:param numpy.array m: model :param numpy.ndarray m: model
:rtype: scipy.csc_matrix :rtype: scipy.sparse.csc_matrix
:return: A(m) :return: A(m)
.. math:: .. math::
+10 -3
View File
@@ -1,5 +1,12 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
from BaseDC import SurveyDC, FieldsDC_CC from .BaseDC import SurveyDC, FieldsDC_CC
class SurveyIP(SurveyDC): class SurveyIP(SurveyDC):
""" """
@@ -52,7 +59,7 @@ class ProblemIP(Problem.BaseProblem):
# sigma = self.curModel.transform # sigma = self.curModel.transform
sigma = self.sigma sigma = self.sigma
Av = self.mesh.aveF2CC Av = self.mesh.aveF2CC
self._Msig = Utils.sdiag(1/(self.mesh.dim * Av.T * (1/sigma))) self._Msig = Utils.sdiag(1//(self.mesh.dim * Av.T * (1/sigma)))
return self._Msig return self._Msig
@property @property
@@ -71,7 +78,7 @@ class ProblemIP(Problem.BaseProblem):
Makes the matrix A(m) for the DC resistivity problem. Makes the matrix A(m) for the DC resistivity problem.
:param numpy.array m: model :param numpy.array m: model
:rtype: scipy.csc_matrix :rtype: scipy.sparse.csc_matrix
:return: A(m) :return: A(m)
.. math:: .. math::
+31 -21
View File
@@ -1,6 +1,16 @@
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from builtins import open
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import map
from builtins import range
from SimPEG import np, Utils from SimPEG import np, Utils
import BaseDC as DC from . import BaseDC as DC
import BaseDC as IP from . import BaseDC as IP
import warnings import warnings
def getActiveindfromTopo(mesh, topo): def getActiveindfromTopo(mesh, topo):
@@ -67,7 +77,7 @@ def readUBC_DC3Dobstopo(filename,mesh,topo,probType="CC"):
if "!" in line.split(): continue if "!" in line.split(): continue
elif line == '\n': continue elif line == '\n': continue
elif line == ' \n': continue elif line == ' \n': continue
temp = map(float, line.split()) temp = list(map(float, line.split()))
# Read a line for the current electrode # Read a line for the current electrode
if len(temp) == 5: # SRC: Only X and Y are provided (assume no topography) if len(temp) == 5: # SRC: Only X and Y are provided (assume no topography)
#TODO consider topography and assign the closest cell center in the earth #TODO consider topography and assign the closest cell center in the earth
@@ -228,10 +238,10 @@ def plot_pseudoSection(DCsurvey, axs, surveyType='dipole-dipole', unitType='volt
elif surveyType == 'dipole-dipole': elif surveyType == 'dipole-dipole':
leg = data * 2*np.pi / ( 1/MA - 1/MB - 1/NB + 1/NA ) leg = data * 2*np.pi / (1/MA - 1/MB - 1/NB + 1/NA)
else: else:
print """unitType must be 'pole-dipole' | 'dipole-dipole' """ print("""unitType must be 'pole-dipole' | 'dipole-dipole' """)
break break
@@ -246,11 +256,11 @@ def plot_pseudoSection(DCsurvey, axs, surveyType='dipole-dipole', unitType='volt
rho = np.hstack([rho,leg]) rho = np.hstack([rho,leg])
else: else:
print """unitType must be 'appResistivity' | 'appConductivity' | 'volt' """ print("""unitType must be 'appResistivity' | 'appConductivity' | 'volt' """)
break break
midx = np.hstack([midx, ( Cmid + Pmid )/2 ]) midx = np.hstack([midx, (Cmid + Pmid)/2])
midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + (Tx[0][2] + Tx[1][2])/2 ]) midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + (Tx[0][2] + Tx[1][2])/2])
# Grid points # Grid points
grid_x, grid_z = np.mgrid[np.min(midx):np.max(midx), np.min(midz):np.max(midz)] grid_x, grid_z = np.mgrid[np.min(midx):np.max(midx), np.min(midz):np.max(midz)]
@@ -340,11 +350,11 @@ def gen_DCIPsurvey(endl, mesh, surveyType, AM_sep, MN_sep, nrx):
dl_x = ( endl[1,0] - endl[0,0] ) / dl_len dl_x = ( endl[1,0] - endl[0,0] ) / dl_len
dl_y = ( endl[1,1] - endl[0,1] ) / dl_len dl_y = ( endl[1,1] - endl[0,1] ) / dl_len
nstn = np.floor( dl_len / AM_sep ) nstn = np.floor(dl_len / AM_sep)
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = endl[0,0] + np.array(range(int(nstn)))*dl_x*AM_sep stn_x = endl[0,0] + np.array(list(range(int(nstn))))*dl_x*AM_sep
stn_y = endl[0,1] + np.array(range(int(nstn)))*dl_y*AM_sep stn_y = endl[0,1] + np.array(list(range(int(nstn))))*dl_y*AM_sep
# Create line of P1 locations # Create line of P1 locations
M = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]] M = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]]
@@ -376,15 +386,15 @@ def gen_DCIPsurvey(endl, mesh, surveyType, AM_sep, MN_sep, nrx):
AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1]) AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1])
# Number of receivers to fit # Number of receivers to fit
nstn = np.min([np.floor( (AB - MN_sep) / AM_sep ) , nrx]) nstn = np.min([(AB - MN_sep) // AM_sep, nrx])
# Check if there is enough space, else break the loop # Check if there is enough space, else break the loop
if nstn <= 0: if nstn <= 0:
continue continue
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = N[ii,0] + dl_x*MN_sep + np.array(range(int(nstn)))*dl_x*AM_sep stn_x = N[ii,0] + dl_x*MN_sep + np.array(list(range(int(nstn))))*dl_x*AM_sep
stn_y = N[ii,1] + dl_y*MN_sep + np.array(range(int(nstn)))*dl_y*AM_sep stn_y = N[ii,1] + dl_y*MN_sep + np.array(list(range(int(nstn))))*dl_y*AM_sep
# Create receiver poles # Create receiver poles
# Create line of P1 locations # Create line of P1 locations
@@ -419,15 +429,15 @@ def gen_DCIPsurvey(endl, mesh, surveyType, AM_sep, MN_sep, nrx):
box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 ) box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 )
box_w = box_l/2. box_w = box_l/2.
nstn = np.floor( box_l / AM_sep ) nstn = box_l // AM_sep
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = min_x + np.array(range(int(nstn)))*dl_x*AM_sep stn_x = min_x + np.array(list(range(int(nstn))))*dl_x*AM_sep
stn_y = min_y + np.array(range(int(nstn)))*dl_y*AM_sep stn_y = min_y + np.array(list(range(int(nstn))))*dl_y*AM_sep
# Define number of cross lines # Define number of cross lines
nlin = int(np.floor( box_w / AM_sep )) nlin = int(box_w // AM_sep)
lind = range(-nlin,nlin+1) lind = list(range(-nlin,nlin+1))
ngrad = nstn * len(lind) ngrad = nstn * len(lind)
@@ -449,7 +459,7 @@ def gen_DCIPsurvey(endl, mesh, surveyType, AM_sep, MN_sep, nrx):
srcClass = DC.SrcDipole([rxClass], M[0,:], N[-1,:]) srcClass = DC.SrcDipole([rxClass], M[0,:], N[-1,:])
SrcList.append(srcClass) SrcList.append(srcClass)
else: else:
print """surveyType must be either 'pole-dipole', 'dipole-dipole' or 'gradient'. """ print("""surveyType must be either 'pole-dipole', 'dipole-dipole' or 'gradient'. """)
survey = DC.SurveyDC(SrcList) survey = DC.SurveyDC(SrcList)
return survey, Tx, Rx return survey, Tx, Rx
@@ -668,7 +678,7 @@ def readUBC_DC3Dobs(fileName, rtype = 'DC'):
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!')
else: else:
print "rtype must be 'DC'(default) | 'IP'" print("rtype must be 'DC'(default) | 'IP'")
# Pre-allocate # Pre-allocate
srcLists = [] srcLists = []
+8 -1
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
import numpy as np import numpy as np
def WennerSrcList(nElecs, aSpacing, in2D=False, plotIt=False): def WennerSrcList(nElecs, aSpacing, in2D=False, plotIt=False):
@@ -5,7 +12,7 @@ def WennerSrcList(nElecs, aSpacing, in2D=False, plotIt=False):
import SimPEG.DCIP as DC import SimPEG.DCIP as DC
elocs = np.arange(0,aSpacing*nElecs,aSpacing) elocs = np.arange(0,aSpacing*nElecs,aSpacing)
elocs -= (nElecs*aSpacing - aSpacing)/2 elocs -= (nElecs*aSpacing - aSpacing) / 2
space = 1 space = 1
WENNER = np.zeros((0,),dtype=int) WENNER = np.zeros((0,),dtype=int)
for ii in range(nElecs): for ii in range(nElecs):
+10 -4
View File
@@ -1,4 +1,10 @@
from BaseDC import * from __future__ import absolute_import
from BaseIP import * from __future__ import unicode_literals
from DCIPUtils import * from __future__ import print_function
import Utils from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .BaseDC import *
from .BaseIP import *
from .DCIPUtils import *
from . import Utils
+13 -6
View File
@@ -1,7 +1,16 @@
import Utils, Survey, Problem, numpy as np, scipy.sparse as sp, gc from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
from . import Utils, Survey, Problem
import numpy as np, scipy.sparse as sp, gc
from future.utils import with_metaclass
class BaseDataMisfit(object): class BaseDataMisfit(with_metaclass(Utils.SimPEGMetaClass, object)):
"""BaseDataMisfit """BaseDataMisfit
.. note:: .. note::
@@ -9,8 +18,6 @@ class BaseDataMisfit(object):
You should inherit from this class to create your own data misfit term. You should inherit from this class to create your own data misfit term.
""" """
__metaclass__ = Utils.SimPEGMetaClass
debug = False #: Print debugging information debug = False #: Print debugging information
counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things counter = None #: Set this to a SimPEG.Utils.Counter() if you want to count things
@@ -93,11 +100,11 @@ class l2_DataMisfit(BaseDataMisfit):
survey = self.survey survey = self.survey
if getattr(survey,'std', None) is None: if getattr(survey,'std', None) is None:
print 'SimPEG.DataMisfit.l2_DataMisfit assigning default std of 5%' print('SimPEG.DataMisfit.l2_DataMisfit assigning default std of 5%')
survey.std = 0.05 survey.std = 0.05
if getattr(survey, 'eps', None) is None: if getattr(survey, 'eps', None) is None:
print 'SimPEG.DataMisfit.l2_DataMisfit assigning default eps of 1e-5 * ||dobs||' print('SimPEG.DataMisfit.l2_DataMisfit assigning default eps of 1e-5 * ||dobs||')
survey.eps = np.linalg.norm(Utils.mkvc(survey.dobs),2)*1e-5 survey.eps = np.linalg.norm(Utils.mkvc(survey.dobs),2)*1e-5
self._Wd = Utils.sdiag(1/(abs(survey.dobs)*survey.std+survey.eps)) self._Wd = Utils.sdiag(1/(abs(survey.dobs)*survey.std+survey.eps))
+82 -49
View File
@@ -1,4 +1,15 @@
import Utils, numpy as np from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import open
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import object
from . import Utils
import numpy as np
class InversionDirective(object): class InversionDirective(object):
"""InversionDirective""" """InversionDirective"""
@@ -15,7 +26,7 @@ class InversionDirective(object):
@inversion.setter @inversion.setter
def inversion(self, i): def inversion(self, i):
if getattr(self,'_inversion',None) is not None: if getattr(self,'_inversion',None) is not None:
print 'Warning: InversionDirective %s has switched to a new inversion.' % self.__name__ print('Warning: InversionDirective %s has switched to a new inversion.' % self.__name__)
self._inversion = i self._inversion = i
@property @property
@@ -68,7 +79,7 @@ class DirectiveList(object):
def inversion(self, i): def inversion(self, i):
if self.inversion is i: return if self.inversion is i: return
if getattr(self,'_inversion',None) is not None: if getattr(self,'_inversion',None) is not None:
print 'Warning: %s has switched to a new inversion.' % self.__name__ print('Warning: %s has switched to a new inversion.' % self.__name__)
for d in self.dList: for d in self.dList:
d.inversion = i d.inversion = i
self._inversion = i self._inversion = i
@@ -120,7 +131,7 @@ class BetaEstimate_ByEig(InversionDirective):
:return: beta0 :return: beta0
""" """
if self.debug: print 'Calculating the beta0 parameter.' if self.debug: print('Calculating the beta0 parameter.')
m = self.invProb.curModel m = self.invProb.curModel
f = self.invProb.getFields(m, store=True, deleteWarmstart=False) f = self.invProb.getFields(m, store=True, deleteWarmstart=False)
@@ -141,7 +152,7 @@ class BetaSchedule(InversionDirective):
def endIter(self): def endIter(self):
if self.opt.iter > 0 and self.opt.iter % self.coolingRate == 0: if self.opt.iter > 0 and self.opt.iter % self.coolingRate == 0:
if self.debug: print 'BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter if self.debug: print('BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter)
self.invProb.beta /= self.coolingFactor self.invProb.beta /= self.coolingFactor
@@ -167,7 +178,7 @@ class TargetMisfit(InversionDirective):
class _SaveEveryIteration(InversionDirective): class SaveEveryIteration(InversionDirective):
@property @property
def name(self): def name(self):
if getattr(self, '_name', None) is None: if getattr(self, '_name', None) is None:
@@ -188,21 +199,21 @@ class _SaveEveryIteration(InversionDirective):
self._fileName = value self._fileName = value
class SaveModelEveryIteration(_SaveEveryIteration): class SaveModelEveryIteration(SaveEveryIteration):
"""SaveModelEveryIteration""" """SaveModelEveryIteration"""
def initialize(self): def initialize(self):
print "SimPEG.SaveModelEveryIteration will save your models as: '###-%s.npy'"%self.fileName print("SimPEG.SaveModelEveryIteration will save your models as: '###-%s.npy'"%self.fileName)
def endIter(self): def endIter(self):
np.save('%03d-%s' % (self.opt.iter, self.fileName), self.opt.xc) np.save('%03d-%s' % (self.opt.iter, self.fileName), self.opt.xc)
class SaveOutputEveryIteration(_SaveEveryIteration): class SaveOutputEveryIteration(SaveEveryIteration):
"""SaveModelEveryIteration""" """SaveModelEveryIteration"""
def initialize(self): def initialize(self):
print "SimPEG.SaveOutputEveryIteration will save your inversion progress as: '###-%s.txt'"%self.fileName print("SimPEG.SaveOutputEveryIteration will save your inversion progress as: '###-%s.txt'"%self.fileName)
f = open(self.fileName+'.txt', 'w') f = open(self.fileName+'.txt', 'w')
f.write(" # beta phi_d phi_m f\n") f.write(" # beta phi_d phi_m f\n")
f.close() f.close()
@@ -212,40 +223,48 @@ class SaveOutputEveryIteration(_SaveEveryIteration):
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.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() f.close()
class SaveOutputDictEveryIteration(_SaveEveryIteration): class SaveOutputDictEveryIteration(SaveEveryIteration):
""" """SaveOutputDictEveryIteration"""
Saves inversion parameters at every iteraion.
"""
def initialize(self): def initialize(self):
print "SimPEG.SaveOutputDictEveryIteration will save your inversion progress as dictionary: '###-%s.npz'"%self.fileName print("SimPEG.SaveOutputDictEveryIteration will save your inversion progress as dictionary: '###-%s.npz'"%self.fileName)
def endIter(self): def endIter(self):
# Initialize the output dict
outDict = {}
# Save the data. # Save the data.
outDict['iter'] = self.opt.iter ms = self.reg.Ws * ( self.reg.mapping * (self.invProb.curModel - self.reg.mref) )
outDict['beta'] = self.invProb.beta phi_ms = 0.5*ms.dot(ms)
outDict['phi_d'] = self.invProb.phi_d if self.reg.mrefInSmooth == True:
outDict['phi_ms'] = self.reg._evalSmall(self.invProb.curModel) mref = self.reg.mref
outDict['phi_mx'] = self.reg._evalSmoothx(self.invProb.curModel) else:
outDict['phi_my'] = self.reg._evalSmoothy(self.invProb.curModel) if self.prob.mesh.dim >= 2 else 'NaN' mref = 0
outDict['phi_mz'] = self.reg._evalSmoothz(self.invProb.curModel) if self.prob.mesh.dim==3 else 'NaN' mx = self.reg.Wx * ( self.reg.mapping * (self.invProb.curModel - mref) )
outDict['f'] = self.opt.f phi_mx = 0.5 * mx.dot(mx)
outDict['m'] = self.invProb.curModel if self.prob.mesh.dim >= 2:
outDict['dpred'] = self.invProb.dpred my = self.reg.Wy * ( self.reg.mapping * (self.invProb.curModel - mref) )
phi_my = 0.5 * my.dot(my)
else:
phi_my = 'NaN'
if self.prob.mesh.dim==3:
mz = self.reg.Wz * ( self.reg.mapping * (self.invProb.curModel - mref) )
phi_mz = 0.5 * mz.dot(mz)
else:
phi_mz = 'NaN'
# Save the file as a npz # Save the file as a npz
np.savez('{:03d}-{:s}'.format(self.opt.iter,self.fileName), outDict) np.savez('{:03d}-{:s}'.format(self.opt.iter,self.fileName), iter=self.opt.iter, beta=self.invProb.beta, phi_d=self.invProb.phi_d, phi_m=self.invProb.phi_m, phi_ms=phi_ms, phi_mx=phi_mx, phi_my=phi_my, phi_mz=phi_mz,f=self.opt.f, m=self.invProb.curModel,dpred=self.invProb.dpred)
# mref = getattr(self, 'm_prev', None)
# if mref is None:
# if self.debug: print 'UpdateReferenceModel is using mref0'
# mref = self.mref0
# self.m_prev = self.invProb.m_current
# return mref
class Update_IRLS(InversionDirective): class Update_IRLS(InversionDirective):
eps_min = None eps_min = None
eps_p = None eps = None
eps_q = None
norms = [2.,2.,2.,2.] norms = [2.,2.,2.,2.]
factor = None factor = None
gamma = None gamma = None
@@ -254,6 +273,7 @@ class Update_IRLS(InversionDirective):
f_old = None f_old = None
f_min_change = 1e-2 f_min_change = 1e-2
beta_tol = 5e-2 beta_tol = 5e-2
prctile = 95
# Solving parameter for IRLS (mode:2) # Solving parameter for IRLS (mode:2)
IRLSiter = 0 IRLSiter = 0
@@ -285,12 +305,25 @@ class Update_IRLS(InversionDirective):
# After reaching target misfit with l2-norm, switch to IRLS (mode:2) # After reaching target misfit with l2-norm, switch to IRLS (mode:2)
if self.invProb.phi_d < self.target and self.mode == 1: if self.invProb.phi_d < self.target and self.mode == 1:
print "Convergence with smooth l2-norm regularization: Start IRLS steps..." print("Convergence with smooth l2-norm regularization: Start IRLS steps...")
self.mode = 2 self.mode = 2
print self.eps_p, self.eps_q, self.norms
self.reg.eps_p = self.eps_p # Either use the supplied epsilon, or fix base on distribution of
self.reg.eps_q = self.eps_q # model values
if getattr(self, 'reg.eps', None) is None:
self.reg.eps_p = np.percentile(np.abs(self.invProb.curModel),self.prctile)
else:
self.reg.eps_p = self.eps[0]
if getattr(self, 'reg.eps', None) is None:
self.reg.eps_q = np.percentile(np.abs(self.reg.regmesh.cellDiffxStencil*(self.reg.mapping * self.invProb.curModel)),self.prctile)
else:
self.reg.eps_q = self.eps[1]
print("L[p qx qy qz]-norm : " + str(self.reg.norms))
print("eps_p: " + str(self.reg.eps_p) + " eps_q: " + str(self.reg.eps_q))
self.reg.norms = self.norms self.reg.norms = self.norms
self.coolingFactor = 1. self.coolingFactor = 1.
self.coolingRate = 1 self.coolingRate = 1
@@ -306,7 +339,7 @@ class Update_IRLS(InversionDirective):
# Beta Schedule # Beta Schedule
if self.opt.iter > 0 and self.opt.iter % self.coolingRate == 0: if self.opt.iter > 0 and self.opt.iter % self.coolingRate == 0:
if self.debug: print 'BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter if self.debug: print('BetaSchedule is cooling Beta. Iteration: %d' % self.opt.iter)
self.invProb.beta /= self.coolingFactor self.invProb.beta /= self.coolingFactor
@@ -318,30 +351,30 @@ class Update_IRLS(InversionDirective):
phim_new = self.reg.eval(self.invProb.curModel) phim_new = self.reg.eval(self.invProb.curModel)
self.f_change = np.abs(self.f_old - phim_new) / self.f_old self.f_change = np.abs(self.f_old - phim_new) / self.f_old
print "Regularization decrease: %6.3e" % (self.f_change) print("Regularization decrease: %6.3e" % (self.f_change))
# Check for maximum number of IRLS cycles # Check for maximum number of IRLS cycles
if self.IRLSiter == self.maxIRLSiter: if self.IRLSiter == self.maxIRLSiter:
print "Reach maximum number of IRLS cycles: %i" % self.maxIRLSiter print("Reach maximum number of IRLS cycles: %i" % self.maxIRLSiter)
self.opt.stopNextIteration = True self.opt.stopNextIteration = True
return return
# Check if the function has changed enough # Check if the function has changed enough
if self.f_change < self.f_min_change and self.IRLSiter > 1: if self.f_change < self.f_min_change and self.IRLSiter > 1:
print "Minimum decrease in regularization. End of IRLS" print("Minimum decrease in regularization. End of IRLS")
self.opt.stopNextIteration = True self.opt.stopNextIteration = True
return return
else: else:
self.f_old = phim_new self.f_old = phim_new
# Cool the threshold parameter if required # # Cool the threshold parameter if required
if getattr(self, 'factor', None) is not None: # if getattr(self, 'factor', None) is not None:
eps = self.reg.eps / self.factor # eps = self.reg.eps / self.factor
#
if getattr(self, 'eps_min', None) is not None: # if getattr(self, 'eps_min', None) is not None:
self.reg.eps = np.max([self.eps_min,eps]) # self.reg.eps = np.max([self.eps_min,eps])
else: # else:
self.reg.eps = eps # self.reg.eps = eps
# Get phi_m at the end of current iteration # Get phi_m at the end of current iteration
self.phi_m_last = self.invProb.phi_m_last self.phi_m_last = self.invProb.phi_m_last
+7
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
import numpy as np import numpy as np
from scipy.constants import mu_0, pi from scipy.constants import mu_0, pi
from scipy import special from scipy import special
+5
View File
@@ -1,4 +1,9 @@
from __future__ import division from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import numpy as np import numpy as np
from scipy.constants import mu_0, pi from scipy.constants import mu_0, pi
from scipy.special import erf from scipy.special import erf
+307
View File
@@ -0,0 +1,307 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import numpy as np
from scipy.constants import mu_0, pi, epsilon_0
from scipy.special import erf
from SimPEG import Utils
omega = lambda f: 2.*np.pi*f
# TODO:
# r = lambda dx, dy, dz: np.sqrt( dx**2. + dy**2. + dz**2.)
# k = lambda f, mu, epsilon, sig: np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
def E_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=0., epsr=1.):
"""
Computing Analytic Electric fields from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
mu = mu_0*(1+kappa)
epsilon = epsilon_0*epsr
sig_hat = sig + 1j*omega(f)*epsilon
XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
# Check
if XYZ.shape[0] > 1 & f.shape[0] > 1:
raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")
dx = XYZ[:,0]-srcLoc[0]
dy = XYZ[:,1]-srcLoc[1]
dz = XYZ[:,2]-srcLoc[2]
r = np.sqrt( dx**2. + dy**2. + dz**2.)
# k = np.sqrt( -1j*2.*np.pi*f*mu*sig )
k = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
front = current * length / (4.*np.pi*sig_hat* r**3) * np.exp(-1j*k*r)
mid = -k**2 * r**2 + 3*1j*k*r + 3
if orientation.upper() == 'X':
Ex = front*((dx**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
Ey = front*(dx*dy / r**2)*mid
Ez = front*(dx*dz / r**2)*mid
return Ex, Ey, Ez
elif orientation.upper() == 'Y':
# x--> y, y--> z, z-->x
Ey = front*((dy**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
Ez = front*(dy*dz / r**2)*mid
Ex = front*(dy*dx / r**2)*mid
return Ex, Ey, Ez
elif orientation.upper() == 'Z':
# x --> z, y --> x, z --> y
Ez = front*((dz**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
Ex = front*(dz*dx / r**2)*mid
Ey = front*(dz*dy / r**2)*mid
return Ex, Ey, Ez
def E_galvanic_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Galvanic portion of Electric fields from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
mu = mu_0*(1+kappa)
epsilon = epsilon_0*epsr
sig_hat = sig + 1j*omega(f)*epsilon
XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
# Check
if XYZ.shape[0] > 1 & f.shape[0] > 1:
raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")
dx = XYZ[:,0]-srcLoc[0]
dy = XYZ[:,1]-srcLoc[1]
dz = XYZ[:,2]-srcLoc[2]
r = np.sqrt( dx**2. + dy**2. + dz**2.)
# k = np.sqrt( -1j*2.*np.pi*f*mu*sig )
k = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
front = current * length / (4.*np.pi*sig_hat* r**3) * np.exp(-1j*k*r)
mid = -k**2 * r**2 + 3*1j*k*r + 3
if orientation.upper() == 'X':
Ex_galvanic = front*((dx**2 / r**2)*mid + (-1j*k*r-1.))
Ey_galvanic = front*(dx*dy / r**2)*mid
Ez_galvanic = front*(dx*dz / r**2)*mid
return Ex_galvanic, Ey_galvanic, Ez_galvanic
elif orientation.upper() == 'Y':
# x--> y, y--> z, z-->x
Ey_galvanic = front*((dy**2 / r**2)*mid + (-1j*k*r-1.))
Ez_galvanic = front*(dy*dz / r**2)*mid
Ex_galvanic = front*(dy*dx / r**2)*mid
return Ex_galvanic, Ey_galvanic, Ez_galvanic
elif orientation.upper() == 'Z':
# x --> z, y --> x, z --> y
Ez_galvanic = front*((dz**2 / r**2)*mid + (-1j*k*r-1.))
Ex_galvanic = front*(dz*dx / r**2)*mid
Ey_galvanic = front*(dz*dy / r**2)*mid
return Ex_galvanic, Ey_galvanic, Ez_galvanic
def E_inductive_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Inductive portion of Electric fields from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
mu = mu_0*(1+kappa)
epsilon = epsilon_0*epsr
sig_hat = sig + 1j*omega(f)*epsilon
XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
# Check
if XYZ.shape[0] > 1 & f.shape[0] > 1:
raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")
dx = XYZ[:,0]-srcLoc[0]
dy = XYZ[:,1]-srcLoc[1]
dz = XYZ[:,2]-srcLoc[2]
r = np.sqrt( dx**2. + dy**2. + dz**2.)
# k = np.sqrt( -1j*2.*np.pi*f*mu*sig )
k = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
front = current * length / (4.*np.pi*sig_hat* r**3) * np.exp(-1j*k*r)
if orientation.upper() == 'X':
Ex_inductive = front*(k**2 * r**2)
Ey_inductive = np.zeros_like(Ex_inductive)
Ez_inductive = np.zeros_like(Ex_inductive)
return Ex_inductive, Ey_inductive, Ez_inductive
elif orientation.upper() == 'Y':
# x--> y, y--> z, z-->x
Ey_inductive = front*(k**2 * r**2)
Ez_inductive = np.zeros_like(Ey_inductive)
Ex_inductive = np.zeros_like(Ey_inductive)
return Ex_inductive, Ey_inductive, Ez_inductive
elif orientation.upper() == 'Z':
# x --> z, y --> x, z --> y
Ez_inductive = front*(k**2 * r**2)
Ex_inductive = np.zeros_like(Ez_inductive)
Ey_inductive = np.zeros_like(Ez_inductive)
return Ex_inductive, Ey_inductive, Ez_inductive
def J_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Current densities from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
Ex, Ey, Ez = E_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=current, length=length, orientation=orientation, kappa=kappa, epsr=epsr)
Jx = sig*Ex
Jy = sig*Ey
Jz = sig*Ez
return Jx, Jy, Jz
def J_galvanic_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Galvanic portion of Current densities from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
Ex_galvanic, Ey_galvanic, Ez_galvanic = E_galvanic_from_ElectricDipoleWholeSpaced(XYZ, srcLoc, sig, f, current=current, length=length, orientation=orientation, kappa=kappa, epsr=epsr)
Jx_galvanic = sig*Ex_galvanic
Jy_galvanic = sig*Ey_galvanic
Jz_galvanic = sig*Ez_galvanic
return Jx_galvanic, Jy_galvanic, Jz_galvanic
def J_inductive_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Inductive portion of Current densities from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
Ex_inductive, Ey_inductive, Ez_inductive = E_inductive_from_ElectricDipoleWholeSpaced(XYZ, srcLoc, sig, f, current=current, length=length, orientation=orientation, kappa=kappa, epsr=epsr)
Jx_inductive = sig*Ex_inductive
Jy_inductive = sig*Ey_inductive
Jz_inductive = sig*Ez_inductive
return Jx_inductive, Jy_inductive, Jz_inductive
def H_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Magnetic fields from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
mu = mu_0*(1+kappa)
epsilon = epsilon_0*epsr
XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
# Check
if XYZ.shape[0] > 1 & f.shape[0] > 1:
raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")
dx = XYZ[:,0]-srcLoc[0]
dy = XYZ[:,1]-srcLoc[1]
dz = XYZ[:,2]-srcLoc[2]
r = np.sqrt( dx**2. + dy**2. + dz**2.)
# k = np.sqrt( -1j*2.*np.pi*f*mu*sig )
k = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
front = current * length / (4.*np.pi* r**2) * (-1j*k*r + 1) * np.exp(-1j*k*r)
if orientation.upper() == 'X':
Hy = front*(-dz / r)
Hz = front*(dy / r)
Hx = np.zeros_like(Hy)
return Hx, Hy, Hz
elif orientation.upper() == 'Y':
Hx = front*(dz / r)
Hz = front*(-dx / r)
Hy = np.zeros_like(Hx)
return Hx, Hy, Hz
elif orientation.upper() == 'Z':
Hx = front*(-dy / r)
Hy = front*(dx / r)
Hz = np.zeros_like(Hx)
return Hx, Hy, Hz
def B_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Magnetic flux densites from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
Hx, Hy, Hz = H_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=current, length=length, orientation=orientation, kappa=kappa, epsr=epsr)
Bx = mu*Hx
By = mu*Hy
Bz = mu*Hz
return Bx, By, Bz
def A_from_ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', kappa=1., epsr=1.):
"""
Computing Electric vector potentials from Electrical Dipole in a Wholespace
TODO:
Add description of parameters
"""
mu = mu_0*(1+kappa)
epsilon = epsilon_0*epsr
XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
# Check
if XYZ.shape[0] > 1 & f.shape[0] > 1:
raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")
dx = XYZ[:,0]-srcLoc[0]
dy = XYZ[:,1]-srcLoc[1]
dz = XYZ[:,2]-srcLoc[2]
r = np.sqrt( dx**2. + dy**2. + dz**2.)
k = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
front = current * length / (4.*np.pi*r)
if orientation.upper() == 'X':
Ax = front*np.exp(-1j*k*r)
Ay = np.zeros_like(Ax)
Az = np.zeros_like(Ax)
return Ax, Ay, Az
elif orientation.upper() == 'Y':
Ay = front*np.exp(-1j*k*r)
Ax = np.zeros_like(Ay)
Az = np.zeros_like(Ay)
return Ax, Ay, Az
elif orientation.upper() == 'Z':
Az = front*np.exp(-1j*k*r)
Ax = np.zeros_like(Ay)
Ay = np.zeros_like(Ay)
return Ax, Ay, Az
+7 -1
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Utils, np from SimPEG import Utils, np
from scipy.constants import mu_0, epsilon_0 from scipy.constants import mu_0, epsilon_0
from SimPEG.EM.Utils.EMUtils import k from SimPEG.EM.Utils.EMUtils import k
@@ -34,7 +40,7 @@ def _getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones
sqrtr2z2 = np.sqrt(r2 + dxyz[:,2]**2) sqrtr2z2 = np.sqrt(r2 + dxyz[:,2]**2)
k2 = k(freq,sigma[2],mu[2],eps) k2 = k(freq,sigma[2],mu[2],eps)
return -HertzZ * np.sqrt(r2) / sqrtr2z2 * (1j*k2 + 1./ sqrtr2z2) return -HertzZ * np.sqrt(r2) / sqrtr2z2 * (1j*k2 + 1. / sqrtr2z2)
def _getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.): def _getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu=mu_0*np.ones(3),eps=epsilon_0,moment=1.):
+6
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import numpy as np import numpy as np
from scipy.constants import mu_0, pi from scipy.constants import mu_0, pi
from scipy.special import erf from scipy.special import erf
+11 -4
View File
@@ -1,4 +1,11 @@
from TDEM import hzAnalyticDipoleT from __future__ import absolute_import
from FDEM import hzAnalyticDipoleF from __future__ import unicode_literals
from FDEMcasing import * from __future__ import print_function
from DC import DCAnalyticHalf, DCAnalyticSphere from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .TDEM import hzAnalyticDipoleT
from .FDEM import hzAnalyticDipoleF
from .FDEMcasing import *
from .DC import DCAnalyticHalf, DCAnalyticSphere
from .FDEMDipolarfields import *
+10 -3
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Survey, Problem, Utils, Models, Maps, PropMaps, np, sp, Solver as SimpegSolver from SimPEG import Survey, Problem, Utils, Models, Maps, PropMaps, np, sp, Solver as SimpegSolver
from scipy.constants import mu_0 from scipy.constants import mu_0
@@ -20,10 +26,10 @@ class BaseEMProblem(Problem.BaseProblem):
Problem.BaseProblem.__init__(self, mesh, **kwargs) Problem.BaseProblem.__init__(self, mesh, **kwargs)
surveyPair = Survey.BaseSurvey surveyPair = Survey.BaseSurvey #: The survey to pair with.
dataPair = Survey.Data dataPair = Survey.Data #: The data to pair with.
PropMap = EMPropMap PropMap = EMPropMap #: The property mapping
Solver = SimpegSolver Solver = SimpegSolver
solverOpts = {} solverOpts = {}
@@ -217,6 +223,7 @@ class BaseEMSurvey(Survey.BaseSurvey):
def eval(self, f): def eval(self, f):
""" """
Project fields to receiver locations Project fields to receiver locations
:param Fields u: fields object :param Fields u: fields object
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: data :return: data
+54 -59
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from builtins import int
from future import standard_library
standard_library.install_aliases()
import numpy as np import numpy as np
import scipy.sparse as sp import scipy.sparse as sp
import SimPEG import SimPEG
@@ -6,11 +13,11 @@ from SimPEG.EM.Utils import omega
from SimPEG.Utils import Zero, Identity, sdiag from SimPEG.Utils import Zero, Identity, sdiag
class Fields(SimPEG.Problem.Fields): class FieldsFDEM(SimPEG.Problem.Fields):
""" """
Fancy Field Storage for a FDEM survey. Only one field type is stored for Fancy Field Storage for a FDEM survey. Only one field type is stored for
each problem, the rest are computed. The fields obejct acts like an array and is indexed by each problem, the rest are computed. The fields object acts like an array and is indexed by
.. code-block:: python .. code-block:: python
@@ -42,7 +49,7 @@ class Fields(SimPEG.Problem.Fields):
:return: total electric field :return: total electric field
""" """
if getattr(self, '_ePrimary', None) is None or getattr(self, '_eSecondary', None) is None: if getattr(self, '_ePrimary', None) is None or getattr(self, '_eSecondary', None) is None:
raise NotImplementedError ('Getting e from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting e from %s is not implemented' %list(self.knownFields.keys())[0])
return self._ePrimary(solution,srcList) + self._eSecondary(solution,srcList) return self._ePrimary(solution,srcList) + self._eSecondary(solution,srcList)
@@ -56,7 +63,7 @@ class Fields(SimPEG.Problem.Fields):
:return: total magnetic flux density :return: total magnetic flux density
""" """
if getattr(self, '_bPrimary', None) is None or getattr(self, '_bSecondary', None) is None: if getattr(self, '_bPrimary', None) is None or getattr(self, '_bSecondary', None) is None:
raise NotImplementedError ('Getting b from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting b from %s is not implemented' %list(self.knownFields.keys())[0])
return self._bPrimary(solution, srcList) + self._bSecondary(solution, srcList) return self._bPrimary(solution, srcList) + self._bSecondary(solution, srcList)
@@ -70,7 +77,7 @@ class Fields(SimPEG.Problem.Fields):
:return: total magnetic field :return: total magnetic field
""" """
if getattr(self, '_hPrimary', None) is None or getattr(self, '_hSecondary', None) is None: if getattr(self, '_hPrimary', None) is None or getattr(self, '_hSecondary', None) is None:
raise NotImplementedError ('Getting h from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting h from %s is not implemented' %list(self.knownFields.keys())[0])
return self._hPrimary(solution, srcList) + self._hSecondary(solution, srcList) return self._hPrimary(solution, srcList) + self._hSecondary(solution, srcList)
@@ -84,7 +91,7 @@ class Fields(SimPEG.Problem.Fields):
:return: total current density :return: total current density
""" """
if getattr(self, '_jPrimary', None) is None or getattr(self, '_jSecondary', None) is None: if getattr(self, '_jPrimary', None) is None or getattr(self, '_jSecondary', None) is None:
raise NotImplementedError ('Getting j from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting j from %s is not implemented' %list(self.knownFields.keys())[0])
return self._jPrimary(solution, srcList) + self._jSecondary(solution, srcList) return self._jPrimary(solution, srcList) + self._jSecondary(solution, srcList)
@@ -92,7 +99,7 @@ class Fields(SimPEG.Problem.Fields):
""" """
Total derivative of e with respect to the inversion model. Returns :math:`d\mathbf{e}/d\mathbf{m}` for forward and (:math:`d\mathbf{e}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint Total derivative of e with respect to the inversion model. Returns :math:`d\mathbf{e}/d\mathbf{m}` for forward and (:math:`d\mathbf{e}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint
:param Src src: sorce :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: source
:param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint) :param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint)
:param numpy.ndarray v: vector to take sensitivity product with :param numpy.ndarray v: vector to take sensitivity product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
@@ -100,7 +107,7 @@ class Fields(SimPEG.Problem.Fields):
:return: derivative times a vector (or tuple for adjoint) :return: derivative times a vector (or tuple for adjoint)
""" """
if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None: if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None:
raise NotImplementedError ('Getting eDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting eDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._eDeriv_u(src, v, adjoint), self._eDeriv_m(src, v, adjoint) return self._eDeriv_u(src, v, adjoint), self._eDeriv_m(src, v, adjoint)
@@ -110,7 +117,7 @@ class Fields(SimPEG.Problem.Fields):
""" """
Total derivative of b with respect to the inversion model. Returns :math:`d\mathbf{b}/d\mathbf{m}` for forward and (:math:`d\mathbf{b}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint Total derivative of b with respect to the inversion model. Returns :math:`d\mathbf{b}/d\mathbf{m}` for forward and (:math:`d\mathbf{b}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint
:param Src src: sorce :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: source
:param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint) :param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint)
:param numpy.ndarray v: vector to take sensitivity product with :param numpy.ndarray v: vector to take sensitivity product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
@@ -118,7 +125,7 @@ class Fields(SimPEG.Problem.Fields):
:return: derivative times a vector (or tuple for adjoint) :return: derivative times a vector (or tuple for adjoint)
""" """
if getattr(self, '_bDeriv_u', None) is None or getattr(self, '_bDeriv_m', None) is None: if getattr(self, '_bDeriv_u', None) is None or getattr(self, '_bDeriv_m', None) is None:
raise NotImplementedError ('Getting bDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting bDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._bDeriv_u(src, v, adjoint), self._bDeriv_m(src, v, adjoint) return self._bDeriv_u(src, v, adjoint), self._bDeriv_m(src, v, adjoint)
@@ -128,7 +135,7 @@ class Fields(SimPEG.Problem.Fields):
""" """
Total derivative of h with respect to the inversion model. Returns :math:`d\mathbf{h}/d\mathbf{m}` for forward and (:math:`d\mathbf{h}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint Total derivative of h with respect to the inversion model. Returns :math:`d\mathbf{h}/d\mathbf{m}` for forward and (:math:`d\mathbf{h}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint
:param Src src: sorce :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: source
:param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint) :param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint)
:param numpy.ndarray v: vector to take sensitivity product with :param numpy.ndarray v: vector to take sensitivity product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
@@ -136,7 +143,7 @@ class Fields(SimPEG.Problem.Fields):
:return: derivative times a vector (or tuple for adjoint) :return: derivative times a vector (or tuple for adjoint)
""" """
if getattr(self, '_hDeriv_u', None) is None or getattr(self, '_hDeriv_m', None) is None: if getattr(self, '_hDeriv_u', None) is None or getattr(self, '_hDeriv_m', None) is None:
raise NotImplementedError ('Getting hDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting hDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._hDeriv_u(src, v, adjoint), self._hDeriv_m(src, v, adjoint) return self._hDeriv_u(src, v, adjoint), self._hDeriv_m(src, v, adjoint)
@@ -146,7 +153,7 @@ class Fields(SimPEG.Problem.Fields):
""" """
Total derivative of j with respect to the inversion model. Returns :math:`d\mathbf{j}/d\mathbf{m}` for forward and (:math:`d\mathbf{j}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint Total derivative of j with respect to the inversion model. Returns :math:`d\mathbf{j}/d\mathbf{m}` for forward and (:math:`d\mathbf{j}/d\mathbf{u}`, :math:`d\mathb{u}/d\mathbf{m}`) for the adjoint
:param Src src: sorce :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: source
:param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint) :param numpy.ndarray du_dm_v: derivative of the solution vector with respect to the model times a vector (is None for adjoint)
:param numpy.ndarray v: vector to take sensitivity product with :param numpy.ndarray v: vector to take sensitivity product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
@@ -154,18 +161,18 @@ class Fields(SimPEG.Problem.Fields):
:return: derivative times a vector (or tuple for adjoint) :return: derivative times a vector (or tuple for adjoint)
""" """
if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None: if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None:
raise NotImplementedError ('Getting jDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting jDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._jDeriv_u(src, v, adjoint), self._jDeriv_m(src, v, adjoint) return self._jDeriv_u(src, v, adjoint), self._jDeriv_m(src, v, adjoint)
return np.array(self._jDeriv_u(src, du_dm_v, adjoint) + self._jDeriv_m(src, v, adjoint), dtype = complex) return np.array(self._jDeriv_u(src, du_dm_v, adjoint) + self._jDeriv_m(src, v, adjoint), dtype = complex)
class Fields3D_e(Fields): class Fields3D_e(FieldsFDEM):
""" """
Fields object for Problem3D_e. Fields object for Problem3D_e.
:param Mesh mesh: mesh :param BaseMesh mesh: mesh
:param Survey survey: survey :param SimPEG.EM.FDEM.SurveyFDEM.Survey survey: survey
""" """
knownFields = {'eSolution':'E'} knownFields = {'eSolution':'E'}
@@ -180,9 +187,6 @@ class Fields3D_e(Fields):
'h' : ['eSolution','CCV','_h'], 'h' : ['eSolution','CCV','_h'],
} }
def __init__(self, mesh, survey, **kwargs):
Fields.__init__(self, mesh, survey, **kwargs)
def startup(self): def startup(self):
self.prob = self.survey.prob self.prob = self.survey.prob
self._edgeCurl = self.survey.prob.mesh.edgeCurl self._edgeCurl = self.survey.prob.mesh.edgeCurl
@@ -288,7 +292,7 @@ class Fields3D_e(Fields):
C = self._edgeCurl C = self._edgeCurl
b = (C * eSolution) b = (C * eSolution)
for i, src in enumerate(srcList): for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq)) b[:,i] *= -1./(1j*omega(src.freq))
s_m, _ = src.eval(self.prob) s_m, _ = src.eval(self.prob)
b[:,i] = b[:,i]+ 1./(1j*omega(src.freq)) * s_m b[:,i] = b[:,i]+ 1./(1j*omega(src.freq)) * s_m
return b return b
@@ -348,7 +352,7 @@ class Fields3D_e(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the current density with respect to the field we solved for with a vector :return: product of the derivative of the current density with respect to the field we solved for with a vector
""" """
n = int(self._aveE2CCV.shape[0] / self._nC) # number of components (instead of checking if cyl or not) n = int(self._aveE2CCV.shape[0] // self._nC) # number of components (instead of checking if cyl or not)
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
@@ -385,8 +389,8 @@ class Fields3D_e(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: magnetic field :return: magnetic field
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # Number of Components n = int(self._aveF2CCV.shape[0] // self._nC) # Number of Components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1. // self.prob.mesh.vol))
return VI * (self._aveF2CCV * (self._MfMui * self._b(eSolution, srcList))) return VI * (self._aveF2CCV * (self._MfMui * self._b(eSolution, srcList)))
@@ -400,7 +404,7 @@ class Fields3D_e(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the magnetic field with respect to the field we solved for with a vector :return: product of the derivative of the magnetic field with respect to the field we solved for with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # Number of Components n = int(self._aveF2CCV.shape[0] // self._nC) # Number of Components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
v = self._MfMui.T * (self._aveF2CCV.T * (VI.T * du_dm_v)) v = self._MfMui.T * (self._aveF2CCV.T * (VI.T * du_dm_v))
@@ -417,7 +421,7 @@ class Fields3D_e(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the magnetic field derivative with respect to the inversion model with a vector :return: product of the magnetic field derivative with respect to the inversion model with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # Number of Components n = int(self._aveF2CCV.shape[0] // self._nC) # Number of Components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
v = self._MfMui.T * (self._aveF2CCV.T * (VI.T * v)) v = self._MfMui.T * (self._aveF2CCV.T * (VI.T * v))
@@ -426,12 +430,12 @@ class Fields3D_e(Fields):
class Fields3D_b(Fields): class Fields3D_b(FieldsFDEM):
""" """
Fields object for Problem3D_b. Fields object for Problem3D_b.
:param Mesh mesh: mesh :param BaseMesh mesh: mesh
:param Survey survey: survey :param SimPEG.EM.FDEM.SurveyFDEM.Survey survey: survey
""" """
knownFields = {'bSolution':'F'} knownFields = {'bSolution':'F'}
@@ -446,9 +450,6 @@ class Fields3D_b(Fields):
'h' : ['bSolution','CCV','_h'], 'h' : ['bSolution','CCV','_h'],
} }
def __init__(self,mesh,survey,**kwargs):
Fields.__init__(self,mesh,survey,**kwargs)
def startup(self): def startup(self):
self.prob = self.survey.prob self.prob = self.survey.prob
self._edgeCurl = self.survey.prob.mesh.edgeCurl self._edgeCurl = self.survey.prob.mesh.edgeCurl
@@ -613,7 +614,7 @@ class Fields3D_b(Fields):
:return: primary current density :return: primary current density
""" """
n = int(self._aveE2CCV.shape[0] / self._nC) # number of components n = int(self._aveE2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveE2CCV * ( self._MeSigma * self._e(bSolution,srcList ) ) ) return VI * (self._aveE2CCV * ( self._MeSigma * self._e(bSolution,srcList ) ) )
@@ -630,7 +631,7 @@ class Fields3D_b(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the current density with respect to the field we solved for with a vector :return: product of the derivative of the current density with respect to the field we solved for with a vector
""" """
n = int(self._aveE2CCV.shape[0] / self._nC) # number of components n = int(self._aveE2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return self._MfMui.T * ( self._edgeCurl * ( self._aveE2CCV.T * (VI.T * du_dm_v) ) ) return self._MfMui.T * ( self._edgeCurl * ( self._aveE2CCV.T * (VI.T * du_dm_v) ) )
@@ -658,7 +659,7 @@ class Fields3D_b(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: magnetic field :return: magnetic field
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) #number of components n = int(self._aveF2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveF2CCV * (self._MfMui * self._b(bSolution, srcList))) return VI * (self._aveF2CCV * (self._MfMui * self._b(bSolution, srcList)))
@@ -673,7 +674,7 @@ class Fields3D_b(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the magnetic field with respect to the field we solved for with a vector :return: product of the derivative of the magnetic field with respect to the field we solved for with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) #number of components n = int(self._aveF2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
@@ -693,12 +694,12 @@ class Fields3D_b(Fields):
return Zero() return Zero()
class Fields3D_j(Fields): class Fields3D_j(FieldsFDEM):
""" """
Fields object for Problem3D_j. Fields object for Problem3D_j.
:param Mesh mesh: mesh :param BaseMesh mesh: mesh
:param Survey survey: survey :param SimPEG.EM.FDEM.SurveyFDEM.Survey survey: survey
""" """
knownFields = {'jSolution':'F'} knownFields = {'jSolution':'F'}
@@ -713,9 +714,6 @@ class Fields3D_j(Fields):
'b' : ['jSolution','CCV','_b'], 'b' : ['jSolution','CCV','_b'],
} }
def __init__(self,mesh,survey,**kwargs):
Fields.__init__(self,mesh,survey,**kwargs)
def startup(self): def startup(self):
self.prob = self.survey.prob self.prob = self.survey.prob
self._edgeCurl = self.survey.prob.mesh.edgeCurl self._edgeCurl = self.survey.prob.mesh.edgeCurl
@@ -899,7 +897,7 @@ class Fields3D_j(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: electric field :return: electric field
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # number of components n = int(self._aveF2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveF2CCV * (self._MfRho * self._j(jSolution, srcList))) return VI * (self._aveF2CCV * (self._MfRho * self._j(jSolution, srcList)))
@@ -913,7 +911,7 @@ class Fields3D_j(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the electric field with respect to the field we solved for with a vector :return: product of the derivative of the electric field with respect to the field we solved for with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # number of components n = int(self._aveF2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return self._MfRho.T * ( self._aveF2CCV.T * ( VI.T * du_dm_v ) ) return self._MfRho.T * ( self._aveF2CCV.T * ( VI.T * du_dm_v ) )
@@ -930,7 +928,7 @@ class Fields3D_j(Fields):
:return: product of the derivative of the electric field with respect to the model with a vector :return: product of the derivative of the electric field with respect to the model with a vector
""" """
jSolution = Utils.mkvc(self[src,'jSolution']) jSolution = Utils.mkvc(self[src,'jSolution'])
n = int(self._aveF2CCV.shape[0] / self._nC) # number of components n = int(self._aveF2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return self._MfRhoDeriv(jSolution).T * ( self._aveF2CCV.T * ( VI.T * v ) ) return self._MfRhoDeriv(jSolution).T * ( self._aveF2CCV.T * ( VI.T * v ) )
@@ -945,7 +943,7 @@ class Fields3D_j(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: secondary magnetic flux density :return: secondary magnetic flux density
""" """
n = int(self._aveE2CCV.shape[0] / self._nC) # number of components n = int(self._aveE2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveE2CCV * ( self._MeMu * self._h(jSolution,srcList)) ) return VI * (self._aveE2CCV * ( self._MeMu * self._h(jSolution,srcList)) )
@@ -960,7 +958,7 @@ class Fields3D_j(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector :return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) # number of components n = int(self._aveF2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
@@ -978,7 +976,7 @@ class Fields3D_j(Fields):
:return: product of the derivative of the magnetic flux density with respect to the model with a vector :return: product of the derivative of the magnetic flux density with respect to the model with a vector
""" """
jSolution = self[src,'jSolution'] jSolution = self[src,'jSolution']
n = int(self._aveE2CCV.shape[0] / self._nC) # number of components n = int(self._aveE2CCV.shape[0] // self._nC) # number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
s_mDeriv,_ = src.evalDeriv(self.prob, adjoint = adjoint) s_mDeriv,_ = src.evalDeriv(self.prob, adjoint = adjoint)
@@ -988,12 +986,12 @@ class Fields3D_j(Fields):
return 1./(1j * omega(src.freq)) * VI * (self._aveE2CCV * ( s_mDeriv(v) - self._edgeCurl.T * ( self._MfRhoDeriv(jSolution) * v ) ) ) return 1./(1j * omega(src.freq)) * VI * (self._aveE2CCV * ( s_mDeriv(v) - self._edgeCurl.T * ( self._MfRhoDeriv(jSolution) * v ) ) )
class Fields3D_h(Fields): class Fields3D_h(FieldsFDEM):
""" """
Fields object for Problem3D_h. Fields object for Problem3D_h.
:param Mesh mesh: mesh :param BaseMesh mesh: mesh
:param Survey survey: survey :param SimPEG.EM.FDEM.SurveyFDEM.Survey survey: survey
""" """
knownFields = {'hSolution':'E'} knownFields = {'hSolution':'E'}
@@ -1008,9 +1006,6 @@ class Fields3D_h(Fields):
'b' : ['hSolution','CCV','_b'], 'b' : ['hSolution','CCV','_b'],
} }
def __init__(self,mesh,survey,**kwargs):
Fields.__init__(self,mesh,survey,**kwargs)
def startup(self): def startup(self):
self.prob = self.survey.prob self.prob = self.survey.prob
self._edgeCurl = self.survey.prob.mesh.edgeCurl self._edgeCurl = self.survey.prob.mesh.edgeCurl
@@ -1163,7 +1158,7 @@ class Fields3D_h(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: electric field :return: electric field
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) #number of components n = int(self._aveF2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveF2CCV * (self._MfRho * self._j(hSolution, srcList))) return VI * (self._aveF2CCV * (self._MfRho * self._j(hSolution, srcList)))
@@ -1177,7 +1172,7 @@ class Fields3D_h(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the electric field with respect to the field we solved for with a vector :return: product of the derivative of the electric field with respect to the field we solved for with a vector
""" """
n = int(self._aveF2CCV.shape[0] / self._nC) #number of components n = int(self._aveF2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return self._edgeCurl.T * ( self._MfRho.T * ( self._aveF2CCV.T * ( VI.T * du_dm_v ) ) ) return self._edgeCurl.T * ( self._MfRho.T * ( self._aveF2CCV.T * ( VI.T * du_dm_v ) ) )
@@ -1194,7 +1189,7 @@ class Fields3D_h(Fields):
:return: product of the electric field derivative with respect to the inversion model with a vector :return: product of the electric field derivative with respect to the inversion model with a vector
""" """
hSolution = Utils.mkvc(self[src,'hSolution']) hSolution = Utils.mkvc(self[src,'hSolution'])
n = int(self._aveF2CCV.shape[0] / self._nC) #number of components n = int(self._aveF2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return ( self._MfRhoDeriv(self._edgeCurl * hSolution).T * ( self._aveF2CCV.T * (VI.T * v) ) ) return ( self._MfRhoDeriv(self._edgeCurl * hSolution).T * ( self._aveF2CCV.T * (VI.T * v) ) )
@@ -1210,7 +1205,7 @@ class Fields3D_h(Fields):
:return: magnetic flux density :return: magnetic flux density
""" """
h = self._h(hSolution, srcList) h = self._h(hSolution, srcList)
n = int(self._aveE2CCV.shape[0] / self._nC) #number of components n = int(self._aveE2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
return VI * (self._aveE2CCV * (self._MeMu * h)) return VI * (self._aveE2CCV * (self._MeMu * h))
@@ -1225,7 +1220,7 @@ class Fields3D_h(Fields):
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector :return: product of the derivative of the magnetic flux density with respect to the field we solved for with a vector
""" """
n = int(self._aveE2CCV.shape[0] / self._nC) #number of components n = int(self._aveE2CCV.shape[0] // self._nC) #number of components
VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol)) VI = sdiag(np.kron(np.ones(n), 1./self.prob.mesh.vol))
if adjoint: if adjoint:
return self._MeMu.T * (self._aveE2CCV.T * ( VI.T * du_dm_v )) return self._MeMu.T * (self._aveE2CCV.T * ( VI.T * du_dm_v ))
+28 -17
View File
@@ -1,7 +1,13 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from SimPEG import Problem, Utils, np, sp, Solver as SimpegSolver from SimPEG import Problem, Utils, np, sp, Solver as SimpegSolver
from scipy.constants import mu_0 from scipy.constants import mu_0
from SurveyFDEM import Survey as SurveyFDEM from .SurveyFDEM import Survey as SurveyFDEM
from FieldsFDEM import Fields, Fields3D_e, Fields3D_b, Fields3D_h, Fields3D_j from .FieldsFDEM import FieldsFDEM, Fields3D_e, Fields3D_b, Fields3D_h, Fields3D_j
from SimPEG.EM.Base import BaseEMProblem from SimPEG.EM.Base import BaseEMProblem
from SimPEG.EM.Utils import omega from SimPEG.EM.Utils import omega
@@ -31,10 +37,11 @@ class BaseFDEMProblem(BaseEMProblem):
if using the H-J formulation (:code:`Problem3D_j` or :code:`Problem3D_h`). Note that here, :math:`\mathbf{s_m}` is an integrated quantity. if using the H-J formulation (:code:`Problem3D_j` or :code:`Problem3D_h`). Note that here, :math:`\mathbf{s_m}` is an integrated quantity.
The problem performs the elimination so that we are solving the system for \\\(\\\mathbf{e},\\\mathbf{b},\\\mathbf{j} \\\) or \\\(\\\mathbf{h}\\\) The problem performs the elimination so that we are solving the system for \\\(\\\mathbf{e},\\\mathbf{b},\\\mathbf{j} \\\) or \\\(\\\mathbf{h}\\\)
""" """
surveyPair = SurveyFDEM surveyPair = SurveyFDEM
fieldsPair = Fields fieldsPair = FieldsFDEM
def fields(self, m): def fields(self, m):
""" """
@@ -64,7 +71,7 @@ class BaseFDEMProblem(BaseEMProblem):
:param numpy.array m: inversion model (nP,) :param numpy.array m: inversion model (nP,)
:param numpy.array v: vector which we take sensitivity product with (nP,) :param numpy.array v: vector which we take sensitivity product with (nP,)
:param SimPEG.EM.FDEM.Fields u: fields object :param SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM u: fields object
:rtype numpy.array: :rtype numpy.array:
:return: Jv (ndata,) :return: Jv (ndata,)
""" """
@@ -99,7 +106,7 @@ class BaseFDEMProblem(BaseEMProblem):
:param numpy.array m: inversion model (nP,) :param numpy.array m: inversion model (nP,)
:param numpy.array v: vector which we take adjoint product with (nP,) :param numpy.array v: vector which we take adjoint product with (nP,)
:param SimPEG.EM.FDEM.Fields u: fields object :param SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM u: fields object
:rtype numpy.array: :rtype numpy.array:
:return: Jv (ndata,) :return: Jv (ndata,)
""" """
@@ -153,8 +160,8 @@ class BaseFDEMProblem(BaseEMProblem):
Evaluates the sources for a given frequency and puts them in matrix form Evaluates the sources for a given frequency and puts them in matrix form
:param float freq: Frequency :param float freq: Frequency
:rtype: (numpy.ndarray, numpy.ndarray) :rtype: tuple
:return: s_m, s_e (nE or nF, nSrc) :return: (s_m, s_e) (nE or nF, nSrc)
""" """
Srcs = self.survey.getSrcByFreq(freq) Srcs = self.survey.getSrcByFreq(freq)
if self._formulation is 'EB': if self._formulation is 'EB':
@@ -194,7 +201,7 @@ class Problem3D_e(BaseFDEMProblem):
which we solve for :math:`\mathbf{e}`. which we solve for :math:`\mathbf{e}`.
:param SimPEG.Mesh mesh: mesh :param SimPEG.Mesh.BaseMesh.BaseMesh mesh: mesh
""" """
_solutionType = 'eSolution' _solutionType = 'eSolution'
@@ -269,7 +276,7 @@ class Problem3D_e(BaseFDEMProblem):
Derivative of the right hand side with respect to the model Derivative of the right hand side with respect to the model
:param float freq: frequency :param float freq: frequency
:param SimPEG.EM.FDEM.Src src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
@@ -305,7 +312,7 @@ class Problem3D_b(BaseFDEMProblem):
.. note :: .. note ::
The inverse problem will not work with full anisotropy The inverse problem will not work with full anisotropy
:param SimPEG.Mesh mesh: mesh :param SimPEG.Mesh.BaseMesh.BaseMesh mesh: mesh
""" """
_solutionType = 'bSolution' _solutionType = 'bSolution'
@@ -400,7 +407,7 @@ class Problem3D_b(BaseFDEMProblem):
Derivative of the right hand side with respect to the model Derivative of the right hand side with respect to the model
:param float freq: frequency :param float freq: frequency
:param SimPEG.EM.FDEM.Src src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
@@ -444,6 +451,7 @@ class Problem3D_j(BaseFDEMProblem):
\mathbf{h} = \\frac{1}{i \omega} \mathbf{M_{\mu}^e}^{-1} \\left(-\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{j} + \mathbf{M^e} \mathbf{s_m} \\right) \mathbf{h} = \\frac{1}{i \omega} \mathbf{M_{\mu}^e}^{-1} \\left(-\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{j} + \mathbf{M^e} \mathbf{s_m} \\right)
and solve for \\\(\\\mathbf{j}\\\) using and solve for \\\(\\\mathbf{j}\\\) using
.. math :: .. math ::
@@ -453,7 +461,7 @@ class Problem3D_j(BaseFDEMProblem):
.. note:: .. note::
This implementation does not yet work with full anisotropy!! This implementation does not yet work with full anisotropy!!
:param SimPEG.Mesh mesh: mesh :param SimPEG.Mesh.BaseMesh.BaseMesh mesh: mesh
""" """
_solutionType = 'jSolution' _solutionType = 'jSolution'
@@ -529,8 +537,8 @@ class Problem3D_j(BaseFDEMProblem):
\mathbf{RHS} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1}\mathbf{s_m} -i\omega \mathbf{s_e} \mathbf{RHS} = \mathbf{C} \mathbf{M_{\mu}^e}^{-1}\mathbf{s_m} -i\omega \mathbf{s_e}
:param float freq: Frequency :param float freq: Frequency
:rtype: numpy.ndarray (nE, nSrc) :rtype: numpy.ndarray
:return: RHS :return: RHS (nE, nSrc)
""" """
s_m, s_e = self.getSourceTerm(freq) s_m, s_e = self.getSourceTerm(freq)
@@ -549,7 +557,7 @@ class Problem3D_j(BaseFDEMProblem):
Derivative of the right hand side with respect to the model Derivative of the right hand side with respect to the model
:param float freq: frequency :param float freq: frequency
:param SimPEG.EM.FDEM.Src src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
@@ -591,7 +599,7 @@ class Problem3D_h(BaseFDEMProblem):
\\left(\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}\\right) \mathbf{h} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{s_e} \\left(\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}\\right) \mathbf{h} = \mathbf{M^e} \mathbf{s_m} + \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{s_e}
:param SimPEG.Mesh mesh: mesh :param SimPEG.Mesh.BaseMesh.BaseMesh mesh: mesh
""" """
_solutionType = 'hSolution' _solutionType = 'hSolution'
@@ -608,9 +616,11 @@ class Problem3D_h(BaseFDEMProblem):
.. math:: .. math::
\mathbf{A} = \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e} \mathbf{A} = \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e}
:param float freq: Frequency :param float freq: Frequency
:rtype: scipy.sparse.csr_matrix :rtype: scipy.sparse.csr_matrix
:return: A :return: A
""" """
MeMu = self.MeMu MeMu = self.MeMu
@@ -653,6 +663,7 @@ class Problem3D_h(BaseFDEMProblem):
:param float freq: Frequency :param float freq: Frequency
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: RHS (nE, nSrc) :return: RHS (nE, nSrc)
""" """
s_m, s_e = self.getSourceTerm(freq) s_m, s_e = self.getSourceTerm(freq)
@@ -666,7 +677,7 @@ class Problem3D_h(BaseFDEMProblem):
Derivative of the right hand side with respect to the model Derivative of the right hand side with respect to the model
:param float freq: frequency :param float freq: frequency
:param SimPEG.EM.FDEM.Src src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
+12 -5
View File
@@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from builtins import super
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG import sp from SimPEG import sp
@@ -25,10 +32,10 @@ class BaseRx(SimPEG.Survey.BaseRx):
def eval(self, src, mesh, f): def eval(self, src, mesh, f):
""" """
Project fields to recievers to get data. Project fields to receivers to get data.
:param Source src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param Mesh mesh: mesh used :param BaseMesh mesh: mesh used
:param Fields f: fields object :param Fields f: fields object
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: fields projected to recievers :return: fields projected to recievers
@@ -44,8 +51,8 @@ class BaseRx(SimPEG.Survey.BaseRx):
""" """
Derivative of projected fields with respect to the inversion model times a vector. Derivative of projected fields with respect to the inversion model times a vector.
:param Source src: FDEM source :param SimPEG.EM.FDEM.SrcFDEM.BaseSrc src: FDEM source
:param Mesh mesh: mesh used :param BaseMesh mesh: mesh used
:param Fields f: fields object :param Fields f: fields object
:param numpy.ndarray v: vector to multiply :param numpy.ndarray v: vector to multiply
:rtype: numpy.ndarray :rtype: numpy.ndarray
+34 -28
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Survey, Problem, Utils, np, sp from SimPEG import Survey, Problem, Utils, np, sp
from scipy.constants import mu_0 from scipy.constants import mu_0
from SimPEG.EM.Utils import * from SimPEG.EM.Utils import *
@@ -23,8 +29,8 @@ class BaseSrc(Survey.BaseSrc):
- :math:`s_m` : magnetic source term - :math:`s_m` : magnetic source term
- :math:`s_e` : electric source term - :math:`s_e` : electric source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: (numpy.ndarray, numpy.ndarray) :rtype: tuple
:return: tuple with magnetic source term and electric source term :return: tuple with magnetic source term and electric source term
""" """
s_m = self.s_m(prob) s_m = self.s_m(prob)
@@ -37,10 +43,10 @@ class BaseSrc(Survey.BaseSrc):
- :code:`s_mDeriv` : derivative of the magnetic source term - :code:`s_mDeriv` : derivative of the magnetic source term
- :code:`s_eDeriv` : derivative of the electric source term - :code:`s_eDeriv` : derivative of the electric source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: (numpy.ndarray, numpy.ndarray) :rtype: tuple
:return: tuple with magnetic source term and electric source term derivatives times a vector :return: tuple with magnetic source term and electric source term derivatives times a vector
""" """
if v is not None: if v is not None:
@@ -52,7 +58,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Primary magnetic flux density Primary magnetic flux density
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic flux density :return: primary magnetic flux density
""" """
@@ -64,7 +70,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Primary magnetic field Primary magnetic field
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -76,7 +82,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Primary electric field Primary electric field
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary electric field :return: primary electric field
""" """
@@ -88,7 +94,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Primary current density Primary current density
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary current density :return: primary current density
""" """
@@ -100,7 +106,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Magnetic source term Magnetic source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: magnetic source term on mesh :return: magnetic source term on mesh
""" """
@@ -110,7 +116,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Electric source term Electric source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: electric source term on mesh :return: electric source term on mesh
""" """
@@ -120,7 +126,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Derivative of magnetic source term with respect to the inversion model Derivative of magnetic source term with respect to the inversion model
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
@@ -133,7 +139,7 @@ class BaseSrc(Survey.BaseSrc):
""" """
Derivative of electric source term with respect to the inversion model Derivative of electric source term with respect to the inversion model
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:param numpy.ndarray v: vector to take product with :param numpy.ndarray v: vector to take product with
:param bool adjoint: adjoint? :param bool adjoint: adjoint?
:rtype: numpy.ndarray :rtype: numpy.ndarray
@@ -162,7 +168,7 @@ class RawVec_e(BaseSrc):
""" """
Electric source term Electric source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: electric source term on mesh :return: electric source term on mesh
""" """
@@ -191,7 +197,7 @@ class RawVec_m(BaseSrc):
""" """
Magnetic source term Magnetic source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: magnetic source term on mesh :return: magnetic source term on mesh
""" """
@@ -220,7 +226,7 @@ class RawVec(BaseSrc):
""" """
Magnetic source term Magnetic source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: magnetic source term on mesh :return: magnetic source term on mesh
""" """
@@ -232,7 +238,7 @@ class RawVec(BaseSrc):
""" """
Electric source term Electric source term
:param Problem prob: FDEM Problem :param BaseFDEMProblem prob: FDEM Problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: electric source term on mesh :return: electric source term on mesh
""" """
@@ -301,7 +307,7 @@ class MagDipole(BaseSrc):
""" """
The primary magnetic flux density from a magnetic vector potential The primary magnetic flux density from a magnetic vector potential
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -339,7 +345,7 @@ class MagDipole(BaseSrc):
""" """
The primary magnetic field from a magnetic vector potential The primary magnetic field from a magnetic vector potential
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -350,7 +356,7 @@ class MagDipole(BaseSrc):
""" """
The magnetic source term The magnetic source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -364,7 +370,7 @@ class MagDipole(BaseSrc):
""" """
The electric source term The electric source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -416,7 +422,7 @@ class MagDipole_Bfield(BaseSrc):
""" """
The primary magnetic flux density from the analytic solution for magnetic fields from a dipole The primary magnetic flux density from the analytic solution for magnetic fields from a dipole
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -455,7 +461,7 @@ class MagDipole_Bfield(BaseSrc):
""" """
The primary magnetic field from a magnetic vector potential The primary magnetic field from a magnetic vector potential
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -466,7 +472,7 @@ class MagDipole_Bfield(BaseSrc):
""" """
The magnetic source term The magnetic source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -479,7 +485,7 @@ class MagDipole_Bfield(BaseSrc):
""" """
The electric source term The electric source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -530,7 +536,7 @@ class CircularLoop(BaseSrc):
""" """
The primary magnetic flux density from a magnetic vector potential The primary magnetic flux density from a magnetic vector potential
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -567,7 +573,7 @@ class CircularLoop(BaseSrc):
""" """
The primary magnetic field from a magnetic vector potential The primary magnetic field from a magnetic vector potential
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -578,7 +584,7 @@ class CircularLoop(BaseSrc):
""" """
The magnetic source term The magnetic source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
@@ -591,7 +597,7 @@ class CircularLoop(BaseSrc):
""" """
The electric source term The electric source term
:param Problem prob: FDEM problem :param BaseFDEMProblem prob: FDEM problem
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: primary magnetic field :return: primary magnetic field
""" """
+8 -2
View File
@@ -1,10 +1,16 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG.EM.Utils import * from SimPEG.EM.Utils import *
from SimPEG.EM.Base import BaseEMSurvey from SimPEG.EM.Base import BaseEMSurvey
from scipy.constants import mu_0 from scipy.constants import mu_0
from SimPEG.Utils import Zero, Identity from SimPEG.Utils import Zero, Identity
import SrcFDEM as Src from . import SrcFDEM as Src
import RxFDEM as Rx from . import RxFDEM as Rx
from SimPEG import sp from SimPEG import sp
class Survey(BaseEMSurvey): class Survey(BaseEMSurvey):
+11 -5
View File
@@ -1,5 +1,11 @@
from SurveyFDEM import Survey from __future__ import absolute_import
import SrcFDEM as Src from __future__ import unicode_literals
import RxFDEM as Rx from __future__ import print_function
from ProblemFDEM import Problem3D_e, Problem3D_b, Problem3D_j, Problem3D_h from __future__ import division
from FieldsFDEM import Fields3D_e, Fields3D_b, Fields3D_j, Fields3D_h from future import standard_library
standard_library.install_aliases()
from .SurveyFDEM import Survey
from . import SrcFDEM as Src
from . import RxFDEM as Rx
from .ProblemFDEM import Problem3D_e, Problem3D_b, Problem3D_j, Problem3D_h
from .FieldsFDEM import Fields3D_e, Fields3D_b, Fields3D_j, Fields3D_h
+6
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import numpy as np import numpy as np
def getxBCyBC_CC(mesh, alpha, beta, gamma): def getxBCyBC_CC(mesh, alpha, beta, gamma):
+9 -3
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG.Utils import Identity, Zero from SimPEG.Utils import Identity, Zero
import numpy as np import numpy as np
@@ -9,7 +15,7 @@ class Fields(SimPEG.Problem.Fields):
def _phiDeriv(self, src, du_dm_v, v, adjoint=False): def _phiDeriv(self, src, du_dm_v, v, adjoint=False):
if getattr(self, '_phiDeriv_u', None) is None or getattr(self, '_phiDeriv_m', None) is None: if getattr(self, '_phiDeriv_u', None) is None or getattr(self, '_phiDeriv_m', None) is None:
raise NotImplementedError ('Getting phiDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting phiDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._phiDeriv_u(src, v, adjoint=adjoint), self._phiDeriv_m(src, v, adjoint=adjoint) return self._phiDeriv_u(src, v, adjoint=adjoint), self._phiDeriv_m(src, v, adjoint=adjoint)
@@ -18,7 +24,7 @@ class Fields(SimPEG.Problem.Fields):
def _eDeriv(self, src, du_dm_v, v, adjoint=False): def _eDeriv(self, src, du_dm_v, v, adjoint=False):
if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None: if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None:
raise NotImplementedError ('Getting eDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting eDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._eDeriv_u(src, v, adjoint), self._eDeriv_m(src, v, adjoint) return self._eDeriv_u(src, v, adjoint), self._eDeriv_m(src, v, adjoint)
@@ -26,7 +32,7 @@ class Fields(SimPEG.Problem.Fields):
def _jDeriv(self, src, du_dm_v, v, adjoint=False): def _jDeriv(self, src, du_dm_v, v, adjoint=False):
if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None: if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None:
raise NotImplementedError ('Getting jDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting jDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._jDeriv_u(src, v, adjoint), self._jDeriv_m(src, v, adjoint) return self._jDeriv_u(src, v, adjoint), self._jDeriv_m(src, v, adjoint)
+9 -3
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG.Utils import Identity, Zero from SimPEG.Utils import Identity, Zero
import numpy as np import numpy as np
@@ -32,7 +38,7 @@ class Fields_ky(SimPEG.Problem.TimeFields):
def _phiDeriv(self,kyInd, src, du_dm_v, v, adjoint=False): def _phiDeriv(self,kyInd, src, du_dm_v, v, adjoint=False):
if getattr(self, '_phiDeriv_u', None) is None or getattr(self, '_phiDeriv_m', None) is None: if getattr(self, '_phiDeriv_u', None) is None or getattr(self, '_phiDeriv_m', None) is None:
raise NotImplementedError ('Getting phiDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting phiDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._phiDeriv_u(kyInd, src, v, adjoint=adjoint), self._phiDeriv_m(kyInd, src, v, adjoint=adjoint) return self._phiDeriv_u(kyInd, src, v, adjoint=adjoint), self._phiDeriv_m(kyInd, src, v, adjoint=adjoint)
@@ -41,7 +47,7 @@ class Fields_ky(SimPEG.Problem.TimeFields):
def _eDeriv(self,kyInd, src, du_dm_v, v, adjoint=False): def _eDeriv(self,kyInd, src, du_dm_v, v, adjoint=False):
if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None: if getattr(self, '_eDeriv_u', None) is None or getattr(self, '_eDeriv_m', None) is None:
raise NotImplementedError ('Getting eDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting eDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._eDeriv_u(kyInd, src, v, adjoint), self._eDeriv_m(kyInd, src, v, adjoint) return self._eDeriv_u(kyInd, src, v, adjoint), self._eDeriv_m(kyInd, src, v, adjoint)
@@ -49,7 +55,7 @@ class Fields_ky(SimPEG.Problem.TimeFields):
def _jDeriv(self,kyInd, src, du_dm_v, v, adjoint=False): def _jDeriv(self,kyInd, src, du_dm_v, v, adjoint=False):
if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None: if getattr(self, '_jDeriv_u', None) is None or getattr(self, '_jDeriv_m', None) is None:
raise NotImplementedError ('Getting jDerivs from %s is not implemented' %self.knownFields.keys()[0]) raise NotImplementedError ('Getting jDerivs from %s is not implemented' %list(self.knownFields.keys())[0])
if adjoint: if adjoint:
return self._jDeriv_u(kyInd, src, v, adjoint), self._jDeriv_m(kyInd, src, v, adjoint) return self._jDeriv_u(kyInd, src, v, adjoint), self._jDeriv_m(kyInd, src, v, adjoint)
+9 -3
View File
@@ -1,11 +1,17 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from SimPEG import Problem, Utils from SimPEG import Problem, Utils
from SimPEG.EM.Base import BaseEMProblem from SimPEG.EM.Base import BaseEMProblem
from SurveyDC import Survey from .SurveyDC import Survey
from FieldsDC import Fields, Fields_CC, Fields_N from .FieldsDC import Fields, Fields_CC, Fields_N
from SimPEG.Utils import sdiag from SimPEG.Utils import sdiag
import numpy as np import numpy as np
from SimPEG.Utils import Zero from SimPEG.Utils import Zero
from BoundaryUtils import getxBCyBC_CC from .BoundaryUtils import getxBCyBC_CC
class BaseDCProblem(BaseEMProblem): class BaseDCProblem(BaseEMProblem):
+10 -3
View File
@@ -1,11 +1,18 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import Problem, Utils from SimPEG import Problem, Utils
from SimPEG.EM.Base import BaseEMProblem from SimPEG.EM.Base import BaseEMProblem
from SurveyDC import Survey, Survey_ky from .SurveyDC import Survey, Survey_ky
from FieldsDC_2D import Fields_ky, Fields_ky_CC, Fields_ky_N from .FieldsDC_2D import Fields_ky, Fields_ky_CC, Fields_ky_N
from SimPEG.Utils import sdiag from SimPEG.Utils import sdiag
import numpy as np import numpy as np
from SimPEG.Utils import Zero from SimPEG.Utils import Zero
from BoundaryUtils import getxBCyBC_CC from .BoundaryUtils import getxBCyBC_CC
class BaseDCProblem_2D(BaseEMProblem): class BaseDCProblem_2D(BaseEMProblem):
+7
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
import SimPEG import SimPEG
import numpy as np import numpy as np
from SimPEG.Utils import Zero, closestPoints from SimPEG.Utils import Zero, closestPoints
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
# from SimPEG.EM.Base import BaseEMSurvey # from SimPEG.EM.Base import BaseEMSurvey
from SimPEG.Utils import Zero, closestPoints, mkvc from SimPEG.Utils import Zero, closestPoints, mkvc
+8 -2
View File
@@ -1,9 +1,15 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG.EM.Base import BaseEMSurvey from SimPEG.EM.Base import BaseEMSurvey
from SimPEG import sp, Survey from SimPEG import sp, Survey
from SimPEG.Utils import Zero, Identity from SimPEG.Utils import Zero, Identity
from RxDC import BaseRx from .RxDC import BaseRx
from SrcDC import BaseSrc from .SrcDC import BaseSrc
class Survey(BaseEMSurvey): class Survey(BaseEMSurvey):
rxPair = BaseRx rxPair = BaseRx
+7
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
import numpy as np import numpy as np
def WennerSrcList(nElecs, aSpacing, in2D=False, plotIt=False): def WennerSrcList(nElecs, aSpacing, in2D=False, plotIt=False):
+14 -8
View File
@@ -1,8 +1,14 @@
from ProblemDC import Problem3D_CC, Problem3D_N from __future__ import absolute_import
from ProblemDC_2D import Problem2D_CC, Problem2D_N from __future__ import unicode_literals
from SurveyDC import Survey, Survey_ky from __future__ import print_function
import SrcDC as Src #Pole from __future__ import division
import RxDC as Rx from future import standard_library
from FieldsDC import Fields_CC standard_library.install_aliases()
from BoundaryUtils import getxBCyBC_CC from .ProblemDC import Problem3D_CC, Problem3D_N
import Utils from .ProblemDC_2D import Problem2D_CC, Problem2D_N
from .SurveyDC import Survey, Survey_ky
from . import SrcDC as Src #Pole
from . import RxDC as Rx
from .FieldsDC import Fields_CC
from .BoundaryUtils import getxBCyBC_CC
from . import Utils
+7 -1
View File
@@ -1,3 +1,9 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from SimPEG import Problem, Utils, Maps, Mesh from SimPEG import Problem, Utils, Maps, Mesh
from SimPEG.EM.Base import BaseEMProblem from SimPEG.EM.Base import BaseEMProblem
from SimPEG.EM.Static.DC.FieldsDC import Fields, Fields_CC, Fields_N from SimPEG.EM.Static.DC.FieldsDC import Fields, Fields_CC, Fields_N
@@ -5,7 +11,7 @@ from SimPEG.Utils import sdiag
import numpy as np import numpy as np
from SimPEG.Utils import Zero from SimPEG.Utils import Zero
from SimPEG.EM.Static.DC import getxBCyBC_CC from SimPEG.EM.Static.DC import getxBCyBC_CC
from SurveyIP import Survey from .SurveyIP import Survey
class IPPropMap(Maps.PropMap): class IPPropMap(Maps.PropMap):
""" """
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
from SimPEG.EM.Base import BaseEMSurvey from SimPEG.EM.Base import BaseEMSurvey
from SimPEG import sp, Survey from SimPEG import sp, Survey
+8 -2
View File
@@ -1,2 +1,8 @@
from ProblemIP import Problem3D_CC, Problem3D_N from __future__ import absolute_import
from SurveyIP import Survey from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .ProblemIP import Problem3D_CC, Problem3D_N
from .SurveyIP import Survey
+10 -2
View File
@@ -1,3 +1,11 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import Problem, Utils, Maps, Mesh from SimPEG import Problem, Utils, Maps, Mesh
from SimPEG.EM.Base import BaseEMProblem from SimPEG.EM.Base import BaseEMProblem
from SimPEG.EM.Static.DC.FieldsDC import Fields, Fields_CC, Fields_N from SimPEG.EM.Static.DC.FieldsDC import Fields, Fields_CC, Fields_N
@@ -5,7 +13,7 @@ from SimPEG.Utils import sdiag
import numpy as np import numpy as np
from SimPEG.Utils import Zero from SimPEG.Utils import Zero
from SimPEG.EM.Static.DC import getxBCyBC_CC from SimPEG.EM.Static.DC import getxBCyBC_CC
from SurveySIP import Survey, Data from .SurveySIP import Survey, Data
class ColeColePropMap(Maps.PropMap): class ColeColePropMap(Maps.PropMap):
""" """
@@ -105,7 +113,7 @@ class BaseSIPProblem(BaseEMProblem):
JvAll = [] JvAll = []
#Assume only eta and tau (eta first then tau) #Assume only eta and tau (eta first then tau)
# v = [2*Mx1] # v = [2*Mx1]
v = v.reshape((int(v.size/2), 2), order='F') v = v.reshape((v.size//2), 2), order='F')
for tind in range(len(self.survey.times)): for tind in range(len(self.survey.times)):
t = self.survey.times[tind] t = self.survey.times[tind]
+7
View File
@@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import Utils, Maps, Mesh, sp, np from SimPEG import Utils, Maps, Mesh, sp, np
from SimPEG.Regularization import BaseRegularization, Simple from SimPEG.Regularization import BaseRegularization, Simple
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
import numpy as np import numpy as np
from SimPEG.Utils import Zero, closestPoints from SimPEG.Utils import Zero, closestPoints
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG import SimPEG
# from SimPEG.EM.Base import BaseEMSurvey # from SimPEG.EM.Base import BaseEMSurvey
from SimPEG.Utils import Zero, closestPoints, mkvc from SimPEG.Utils import Zero, closestPoints, mkvc
+7
View File
@@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import str
import SimPEG import SimPEG
from SimPEG.EM.Base import BaseEMSurvey from SimPEG.EM.Base import BaseEMSurvey
from SimPEG import np, sp, Survey, Utils from SimPEG import np, sp, Survey, Utils
+11 -5
View File
@@ -1,5 +1,11 @@
from ProblemSIP import Problem3D_CC, Problem3D_N from __future__ import absolute_import
from SurveySIP import Survey, Data from __future__ import unicode_literals
import SrcSIP as Src #Pole from __future__ import print_function
import RxSIP as Rx from __future__ import division
from Regularization import MultiRegularization from future import standard_library
standard_library.install_aliases()
from .ProblemSIP import Problem3D_CC, Problem3D_N
from .SurveySIP import Survey, Data
from . import SrcSIP as Src #Pole
from . import RxSIP as Rx
from .Regularization import MultiRegularization
+27 -19
View File
@@ -1,3 +1,11 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import np from SimPEG import np
from SimPEG.EM.Static import DC, IP from SimPEG.EM.Static import DC, IP
@@ -85,10 +93,10 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
elif stype == 'dpdp': elif stype == 'dpdp':
leg = data * 2*np.pi / ( 1/MA - 1/MB + 1/NB - 1/NA ) leg = data * 2*np.pi / (1/MA - 1/MB + 1/NB - 1/NA)
LEG.append(1./(2*np.pi) *( 1/MA - 1/MB + 1/NB - 1/NA )) LEG.append(1./(2*np.pi) * (1/MA - 1/MB + 1/NB - 1/NA))
else: else:
print """dtype must be 'pdp'(pole-dipole) | 'dpdp' (dipole-dipole) """ print("""dtype must be 'pdp'(pole-dipole) | 'dpdp' (dipole-dipole) """)
break break
@@ -103,7 +111,7 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
rho = np.hstack([rho,leg]) rho = np.hstack([rho,leg])
else: else:
print """dtype must be 'appr' | 'appc' | 'volt' """ print("""dtype must be 'appr' | 'appc' | 'volt' """)
break break
@@ -184,14 +192,14 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
# Mesure survey length and direction # Mesure survey length and direction
dl_len = xy_2_r(endl[0,0],endl[1,0],endl[0,1],endl[1,1]) dl_len = xy_2_r(endl[0,0],endl[1,0],endl[0,1],endl[1,1])
dl_x = ( endl[1,0] - endl[0,0] ) / dl_len dl_x = (endl[1,0] - endl[0,0]) / dl_len
dl_y = ( endl[1,1] - endl[0,1] ) / dl_len dl_y = (endl[1,1] - endl[0,1]) / dl_len
nstn = np.floor( dl_len / a ) nstn = np.floor(dl_len / a)
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = endl[0,0] + np.array(range(int(nstn)))*dl_x*a stn_x = endl[0,0] + np.array(list(range(int(nstn))))*dl_x*a
stn_y = endl[0,1] + np.array(range(int(nstn)))*dl_y*a stn_y = endl[0,1] + np.array(list(range(int(nstn))))*dl_y*a
if mesh.dim==2: if mesh.dim==2:
ztop = mesh.vectorNy[-1] ztop = mesh.vectorNy[-1]
@@ -230,15 +238,15 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1]) AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1])
# Number of receivers to fit # Number of receivers to fit
nstn = np.min([np.floor( (AB - b) / a ) , n]) nstn = np.min([(AB - b) // a, n])
# Check if there is enough space, else break the loop # Check if there is enough space, else break the loop
if nstn <= 0: if nstn <= 0:
continue continue
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = N[ii,0] + dl_x*b + np.array(range(int(nstn)))*dl_x*a stn_x = N[ii,0] + dl_x*b + np.array(list(range(int(nstn))))*dl_x*a
stn_y = N[ii,1] + dl_y*b + np.array(range(int(nstn)))*dl_y*a stn_y = N[ii,1] + dl_y*b + np.array(list(range(int(nstn))))*dl_y*a
# Create receiver poles # Create receiver poles
@@ -275,17 +283,17 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
max_y = endl[1,1] - dl_y * b max_y = endl[1,1] - dl_y * b
box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 ) box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 )
box_w = box_l/2. box_w = box_l / 2.
nstn = np.floor( box_l / a ) nstn = np.floor(box_l / a)
# Compute discrete pole location along line # Compute discrete pole location along line
stn_x = min_x + np.array(range(int(nstn)))*dl_x*a stn_x = min_x + np.array(list(range(int(nstn))))*dl_x*a
stn_y = min_y + np.array(range(int(nstn)))*dl_y*a stn_y = min_y + np.array(list(range(int(nstn))))*dl_y*a
# Define number of cross lines # Define number of cross lines
nlin = int(np.floor( box_w / a )) nlin = int(box_w // a)
lind = range(-nlin,nlin+1) lind = list(range(-nlin,nlin+1))
ngrad = nstn * len(lind) ngrad = nstn * len(lind)
@@ -310,7 +318,7 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
srcClass = DC.Src.Dipole([rxClass], M[0,:], N[-1,:]) srcClass = DC.Src.Dipole([rxClass], M[0,:], N[-1,:])
SrcList.append(srcClass) SrcList.append(srcClass)
else: else:
print """stype must be either 'pdp', 'dpdp' or 'gradient'. """ print("""stype must be either 'pdp', 'dpdp' or 'gradient'. """)
return SrcList return SrcList
+7 -1
View File
@@ -1 +1,7 @@
from StaticUtils import * from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .StaticUtils import *
+9 -3
View File
@@ -1,3 +1,9 @@
import DC from __future__ import absolute_import
import IP from __future__ import unicode_literals
import SIP from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from . import DC
from . import IP
from . import SIP
+24 -17
View File
@@ -1,3 +1,10 @@
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import Solver, Problem from SimPEG import Solver, Problem
from SimPEG.Problem import BaseTimeProblem from SimPEG.Problem import BaseTimeProblem
from SimPEG.EM.Utils import * from SimPEG.EM.Utils import *
@@ -47,7 +54,7 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
self.waveformType = "GENERAL" self.waveformType = "GENERAL"
def fields(self, m): def fields(self, m):
if self.verbose: print '%s\nCalculating fields(m)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nCalculating fields(m)\n%s'%('*'*50,'*'*50))
self.curModel = m self.curModel = m
# Create a fields storage object # Create a fields storage object
F = self._FieldsForward_pair(self.mesh, self.survey) F = self._FieldsForward_pair(self.mesh, self.survey)
@@ -55,7 +62,7 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
# Set the initial conditions # Set the initial conditions
F[src,:,0] = src.getInitialFields(self.mesh) F[src,:,0] = src.getInitialFields(self.mesh)
F = self.forward(m, self.getRHS, F=F) F = self.forward(m, self.getRHS, F=F)
if self.verbose: print '%s\nDone calculating fields(m)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nDone calculating fields(m)\n%s'%('*'*50,'*'*50))
return F return F
def forward(self, m, RHS, F=None): def forward(self, m, RHS, F=None):
@@ -70,13 +77,13 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
if Ainv is not None: if Ainv is not None:
Ainv.clean() Ainv.clean()
A = self.getA(tInd) A = self.getA(tInd)
if self.verbose: print 'Factoring... (dt = %e)'%dt if self.verbose: print('Factoring... (dt = %e)'%dt)
Ainv = self.Solver(A, **self.solverOpts) Ainv = self.Solver(A, **self.solverOpts)
if self.verbose: print 'Done' if self.verbose: print('Done')
rhs = RHS(tInd, F) rhs = RHS(tInd, F)
if self.verbose: print ' Solving... (tInd = %d)'%tInd if self.verbose: print(' Solving... (tInd = %d)'%tInd)
sol = Ainv * rhs sol = Ainv * rhs
if self.verbose: print ' Done...' if self.verbose: print(' Done...')
if sol.ndim == 1: if sol.ndim == 1:
sol.shape = (sol.size,1) sol.shape = (sol.size,1)
F[:,self.solType,tInd+1] = sol F[:,self.solType,tInd+1] = sol
@@ -95,13 +102,13 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
if Ainv is not None: if Ainv is not None:
Ainv.clean() Ainv.clean()
A = self.getA(tInd) A = self.getA(tInd)
if self.verbose: print 'Factoring (Adjoint)... (dt = %e)'%dt if self.verbose: print('Factoring (Adjoint)... (dt = %e)'%dt)
Ainv = self.Solver(A, **self.solverOpts) Ainv = self.Solver(A, **self.solverOpts)
if self.verbose: print 'Done' if self.verbose: print('Done')
rhs = RHS(tInd, F) rhs = RHS(tInd, F)
if self.verbose: print ' Solving (Adjoint)... (tInd = %d)'%tInd if self.verbose: print(' Solving (Adjoint)... (tInd = %d)'%tInd)
sol = Ainv * rhs sol = Ainv * rhs
if self.verbose: print ' Done...' if self.verbose: print(' Done...')
if sol.ndim == 1: if sol.ndim == 1:
sol.shape = (sol.size,1) sol.shape = (sol.size,1)
F[:,self.solType,tInd+1] = sol F[:,self.solType,tInd+1] = sol
@@ -112,7 +119,7 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param numpy.ndarray v: vector (model object) :param numpy.ndarray v: vector (model object)
:param simpegEM.TDEM.FieldsTDEM f: Fields resulting from m :param FieldsTDEM f: Fields resulting from m
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: w (data object) :return: w (data object)
@@ -123,21 +130,21 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
* Compute \\\(\\\\vec{w} = -\\\mathbf{Q} \\\\vec{y}\\\) * Compute \\\(\\\\vec{w} = -\\\mathbf{Q} \\\\vec{y}\\\)
""" """
if self.verbose: print '%s\nCalculating J(v)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nCalculating J(v)\n%s'%('*'*50,'*'*50))
self.curModel = m self.curModel = m
if f is None: if f is None:
f = self.fields(m) f = self.fields(m)
p = self.Gvec(m, v, f) p = self.Gvec(m, v, f)
y = self.solveAh(m, p) y = self.solveAh(m, p)
Jv = self.survey.evalDeriv(f, v=y) Jv = self.survey.evalDeriv(f, v=y)
if self.verbose: print '%s\nDone calculating J(v)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nDone calculating J(v)\n%s'%('*'*50,'*'*50))
return - mkvc(Jv) return - mkvc(Jv)
def Jtvec(self, m, v, f=None): def Jtvec(self, m, v, f=None):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param numpy.ndarray,SimPEG.Survey.Data v: vector (data object) :param numpy.ndarray v: vector (or a :class:`SimPEG.Survey.Data` object)
:param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m :param FieldsTDEM u: Fields resulting from m
:rtype: numpy.ndarray :rtype: numpy.ndarray
:return: w (model object) :return: w (model object)
@@ -148,7 +155,7 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
* Compute \\\(\\\\vec{w} = -\\\mathbf{G}^\\\\top y\\\) * Compute \\\(\\\\vec{w} = -\\\mathbf{G}^\\\\top y\\\)
""" """
if self.verbose: print '%s\nCalculating J^T(v)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nCalculating J^T(v)\n%s'%('*'*50,'*'*50))
self.curModel = m self.curModel = m
if f is None: if f is None:
f = self.fields(m) f = self.fields(m)
@@ -159,6 +166,6 @@ class BaseTDEMProblem(BaseTimeProblem, BaseEMProblem):
p = self.survey.evalDeriv(f, v=v, adjoint=True) p = self.survey.evalDeriv(f, v=v, adjoint=True)
y = self.solveAht(m, p) y = self.solveAht(m, p)
w = self.Gtvec(m, y, f) w = self.Gtvec(m, y, f)
if self.verbose: print '%s\nDone calculating J^T(v)\n%s'%('*'*50,'*'*50) if self.verbose: print('%s\nDone calculating J^T(v)\n%s'%('*'*50,'*'*50))
return - mkvc(w) return - mkvc(w)
+11 -5
View File
@@ -1,7 +1,13 @@
from __future__ import print_function
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from SimPEG import Utils, Survey, np from SimPEG import Utils, Survey, np
from SimPEG.Survey import BaseSurvey from SimPEG.Survey import BaseSurvey
from SimPEG.EM.Utils import * from SimPEG.EM.Utils import *
from BaseTDEM import FieldsTDEM from .BaseTDEM import FieldsTDEM
class RxTDEM(Survey.BaseTimeRx): class RxTDEM(Survey.BaseTimeRx):
@@ -87,7 +93,7 @@ class SrcTDEM_VMD_MVP(SrcTDEM):
def getInitialFields(self, mesh): def getInitialFields(self, mesh):
"""Vertical magnetic dipole, magnetic vector potential""" """Vertical magnetic dipole, magnetic vector potential"""
if self.waveformType == "STEPOFF": if self.waveformType == "STEPOFF":
print ">> Step waveform: Non-zero initial condition" print(">> Step waveform: Non-zero initial condition")
if mesh._meshType is 'CYL': if mesh._meshType is 'CYL':
if mesh.isSymmetric: if mesh.isSymmetric:
MVP = MagneticDipoleVectorPotential(self.loc, mesh, 'Ey') MVP = MagneticDipoleVectorPotential(self.loc, mesh, 'Ey')
@@ -99,7 +105,7 @@ class SrcTDEM_VMD_MVP(SrcTDEM):
raise Exception('Unknown mesh for VMD') raise Exception('Unknown mesh for VMD')
return {"b": mesh.edgeCurl*MVP} return {"b": mesh.edgeCurl*MVP}
elif self.waveformType == "GENERAL": elif self.waveformType == "GENERAL":
print ">> General waveform: Zero initial condition" print(">> General waveform: Zero initial condition")
return {"b": np.zeros(mesh.nF)} return {"b": np.zeros(mesh.nF)}
else: else:
raise NotImplementedError("Only use STEPOFF or GENERAL") raise NotImplementedError("Only use STEPOFF or GENERAL")
@@ -127,7 +133,7 @@ class SrcTDEM_CircularLoop_MVP(SrcTDEM):
def getInitialFields(self, mesh): def getInitialFields(self, mesh):
"""Circular Loop, magnetic vector potential""" """Circular Loop, magnetic vector potential"""
if self.waveformType == "STEPOFF": if self.waveformType == "STEPOFF":
print ">> Step waveform: Non-zero initial condition" print(">> Step waveform: Non-zero initial condition")
if mesh._meshType is 'CYL': if mesh._meshType is 'CYL':
if mesh.isSymmetric: if mesh.isSymmetric:
MVP = MagneticLoopVectorPotential(self.loc, mesh, 'Ey', self.radius) MVP = MagneticLoopVectorPotential(self.loc, mesh, 'Ey', self.radius)
@@ -139,7 +145,7 @@ class SrcTDEM_CircularLoop_MVP(SrcTDEM):
raise Exception('Unknown mesh for CircularLoop') raise Exception('Unknown mesh for CircularLoop')
return {"b": mesh.edgeCurl*MVP} return {"b": mesh.edgeCurl*MVP}
elif self.waveformType == "GENERAL": elif self.waveformType == "GENERAL":
print ">> General waveform: Zero initial condition" print(">> General waveform: Zero initial condition")
return {"b": np.zeros(mesh.nF)} return {"b": np.zeros(mesh.nF)}
else: else:
raise NotImplementedError("Only use STEPOFF or GENERAL") raise NotImplementedError("Only use STEPOFF or GENERAL")
+22 -15
View File
@@ -1,7 +1,14 @@
from BaseTDEM import BaseTDEMProblem, FieldsTDEM from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import range
from .BaseTDEM import BaseTDEMProblem, FieldsTDEM
from SimPEG.Utils import mkvc, sdiag from SimPEG.Utils import mkvc, sdiag
import numpy as np import numpy as np
from SurveyTDEM import SurveyTDEM from .SurveyTDEM import SurveyTDEM
class FieldsTDEM_e_from_b(FieldsTDEM): class FieldsTDEM_e_from_b(FieldsTDEM):
@@ -87,8 +94,8 @@ class ProblemTDEM_b(BaseTDEMProblem):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param numpy.array vec: vector (like a model) :param numpy.array vec: vector (like a model)
:param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m :param FieldsTDEM u: Fields resulting from m
:rtype: simpegEM.TDEM.FieldsTDEM :rtype: FieldsTDEM
:return: f :return: f
Multiply G by a vector Multiply G by a vector
@@ -125,9 +132,9 @@ class ProblemTDEM_b(BaseTDEMProblem):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param numpy.array vec: vector (like a fields) :param numpy.array vec: vector (like a fields)
:param simpegEM.TDEM.FieldsTDEM u: Fields resulting from m :param FieldsTDEM u: Fields resulting from m
:rtype: np.ndarray (like a model) :rtype: numpy.ndarray
:return: p :return: p (like a model)
Multiply G.T by a vector Multiply G.T by a vector
""" """
@@ -153,8 +160,8 @@ class ProblemTDEM_b(BaseTDEMProblem):
def solveAh(self, m, p): def solveAh(self, m, p):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param simpegEM.TDEM.FieldsTDEM p: Fields object :param FieldsTDEM p: Fields object
:rtype: simpegEM.TDEM.FieldsTDEM :rtype: FieldsTDEM
:return: y :return: y
Solve the block-matrix system \\\(\\\hat{A} \\\hat{y} = \\\hat{p}\\\): Solve the block-matrix system \\\(\\\hat{A} \\\hat{y} = \\\hat{p}\\\):
@@ -200,8 +207,8 @@ class ProblemTDEM_b(BaseTDEMProblem):
def solveAht(self, m, p): def solveAht(self, m, p):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param simpegEM.TDEM.FieldsTDEM p: Fields object :param FieldsTDEM p: Fields object
:rtype: simpegEM.TDEM.FieldsTDEM :rtype: FieldsTDEM
:return: y :return: y
Solve the block-matrix system \\\(\\\hat{A}^\\\\top \\\hat{y} = \\\hat{p}\\\): Solve the block-matrix system \\\(\\\hat{A}^\\\\top \\\hat{y} = \\\hat{p}\\\):
@@ -270,8 +277,8 @@ class ProblemTDEM_b(BaseTDEMProblem):
def _AhVec(self, m, vec): def _AhVec(self, m, vec):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param simpegEM.TDEM.FieldsTDEM vec: Fields object :param FieldsTDEM vec: Fields object
:rtype: simpegEM.TDEM.FieldsTDEM :rtype: FieldsTDEM
:return: f :return: f
Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where
@@ -315,8 +322,8 @@ class ProblemTDEM_b(BaseTDEMProblem):
def _AhtVec(self, m, vec): def _AhtVec(self, m, vec):
""" """
:param numpy.array m: Conductivity model :param numpy.array m: Conductivity model
:param simpegEM.TDEM.FieldsTDEM vec: Fields object :param FieldsTDEM vec: Fields object
:rtype: simpegEM.TDEM.FieldsTDEM :rtype: FieldsTDEM
:return: f :return: f
Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where Multiply the matrix \\\(\\\hat{A}\\\) by a fields vector where
+9 -3
View File
@@ -1,3 +1,9 @@
from SurveyTDEM import * #SurveyTDEM, RxTDEM, SrcTDEM from __future__ import absolute_import
from BaseTDEM import BaseTDEMProblem, FieldsTDEM from __future__ import unicode_literals
from TDEM_b import ProblemTDEM_b from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .SurveyTDEM import * #SurveyTDEM, RxTDEM, SrcTDEM
from .BaseTDEM import BaseTDEMProblem, FieldsTDEM
from .TDEM_b import ProblemTDEM_b
+12 -5
View File
@@ -1,3 +1,10 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
from scipy.special import ellipk, ellipe from scipy.special import ellipk, ellipe
from scipy.constants import mu_0, pi from scipy.constants import mu_0, pi
@@ -17,7 +24,7 @@ def MagneticDipoleVectorPotential(srcLoc, obsLoc, component, moment=1., dipoleMo
#TODO: break this out! #TODO: break this out!
if type(component) in [list, tuple]: if type(component) in [list, tuple]:
out = range(len(component)) out = list(range(len(component)))
for i, comp in enumerate(component): for i, comp in enumerate(component):
out[i] = MagneticDipoleVectorPotential(srcLoc, obsLoc, comp, dipoleMoment=dipoleMoment) out[i] = MagneticDipoleVectorPotential(srcLoc, obsLoc, comp, dipoleMoment=dipoleMoment)
return np.concatenate(out) return np.concatenate(out)
@@ -118,7 +125,7 @@ def MagneticLoopVectorPotential(srcLoc, obsLoc, component, radius, mu=mu_0):
""" """
if type(component) in [list, tuple]: if type(component) in [list, tuple]:
out = range(len(component)) out = list(range(len(component)))
for i, comp in enumerate(component): for i, comp in enumerate(component):
out[i] = MagneticLoopVectorPotential(srcLoc, obsLoc, comp, radius, mu) out[i] = MagneticLoopVectorPotential(srcLoc, obsLoc, comp, radius, mu)
return np.concatenate(out) return np.concatenate(out)
@@ -158,11 +165,11 @@ def MagneticLoopVectorPotential(srcLoc, obsLoc, component, radius, mu=mu_0):
# % 1/r singular at r = 0 and K(m) singular at m = 1 # % 1/r singular at r = 0 and K(m) singular at m = 1
Aphi = np.zeros(n) Aphi = np.zeros(n)
# % Common factor is (mu * I) / pi with I = 1 and mu = 4e-7 * pi. # % Common factor is (mu * I) / pi with I = 1 and mu = 4e-7 * pi.
Aphi[ind] = 4e-7 / np.sqrt(m[ind]) * np.sqrt(radius / r[ind]) *((1. - m[ind] / 2.) * K[ind] - E[ind]) Aphi[ind] = 4e-7 / np.sqrt(m[ind]) * np.sqrt(radius/ r[ind]) *((1. - m[ind] / 2.) * K[ind] - E[ind])
if component == 'x': if component == 'x':
A[ind, i] = Aphi[ind] * (-y[ind] / r[ind] ) A[ind, i] = Aphi[ind] * (-y[ind] / r[ind])
elif component == 'y': elif component == 'y':
A[ind, i] = Aphi[ind] * ( x[ind] / r[ind] ) A[ind, i] = Aphi[ind] * (x[ind] / r[ind])
else: else:
raise ValueError('Invalid component') raise ValueError('Invalid component')
+8 -2
View File
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import numpy as np import numpy as np
from scipy.constants import mu_0, epsilon_0 from scipy.constants import mu_0, epsilon_0
@@ -9,8 +15,8 @@ def omega(freq):
def k(freq, sigma, mu=mu_0, eps=epsilon_0): def k(freq, sigma, mu=mu_0, eps=epsilon_0):
""" Eq 1.47 - 1.49 in Ward and Hohmann """ """ Eq 1.47 - 1.49 in Ward and Hohmann """
w = omega(freq) w = omega(freq)
alp = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w))**2 ) + 1) ) alp = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w)))**2 ) + 1)
beta = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w))**2 ) - 1) ) beta = w * np.sqrt( mu*eps/2 * ( np.sqrt(1. + (sigma / (eps*w)))**2 ) - 1)
return alp - 1j*beta return alp - 1j*beta
+8 -2
View File
@@ -1,2 +1,8 @@
from EMUtils import omega, k from __future__ import absolute_import
from AnalyticUtils import MagneticDipoleFields, MagneticDipoleVectorPotential, MagneticLoopVectorPotential from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .EMUtils import omega, k
from .AnalyticUtils import MagneticDipoleFields, MagneticDipoleVectorPotential, MagneticLoopVectorPotential
+13 -6
View File
@@ -1,3 +1,10 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import int
from future import standard_library
standard_library.install_aliases()
import unittest import unittest
from SimPEG import * from SimPEG import *
from SimPEG import EM from SimPEG import EM
@@ -58,7 +65,7 @@ def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False):
Src.append(EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct()*S_m, S_e)) Src.append(EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct()*S_m, S_e))
if verbose: if verbose:
print ' Fetching %s problem' % (fdemType) print(' Fetching %s problem' % (fdemType))
if fdemType == 'e': if fdemType == 'e':
survey = EM.FDEM.Survey(Src) survey = EM.FDEM.Survey(Src)
@@ -83,7 +90,7 @@ def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False):
try: try:
from pymatsolver import MumpsSolver from pymatsolver import MumpsSolver
prb.Solver = MumpsSolver prb.Solver = MumpsSolver
except ImportError, e: except ImportError as e:
prb.Solver = SolverLU prb.Solver = SolverLU
return prb return prb
@@ -94,7 +101,7 @@ def crossCheckTest(SrcList, fdemType1, fdemType2, comp, addrandoms = False, useM
prb1 = getFDEMProblem(fdemType1, comp, SrcList, freq, useMu, verbose) prb1 = getFDEMProblem(fdemType1, comp, SrcList, freq, useMu, verbose)
mesh = prb1.mesh mesh = prb1.mesh
print 'Cross Checking Forward: %s, %s formulations - %s' % (fdemType1, fdemType2, comp) print('Cross Checking Forward: %s, %s formulations - %s' % (fdemType1, fdemType2, comp))
logsig = np.log(np.ones(mesh.nC)*CONDUCTIVITY) logsig = np.log(np.ones(mesh.nC)*CONDUCTIVITY)
mu = np.ones(mesh.nC)*MU mu = np.ones(mesh.nC)*MU
@@ -112,7 +119,7 @@ def crossCheckTest(SrcList, fdemType1, fdemType2, comp, addrandoms = False, useM
d1 = survey1.dpred(m) d1 = survey1.dpred(m)
if verbose: if verbose:
print ' Problem 1 solved' print(' Problem 1 solved')
prb2 = getFDEMProblem(fdemType2, comp, SrcList, freq, useMu, verbose) prb2 = getFDEMProblem(fdemType2, comp, SrcList, freq, useMu, verbose)
@@ -121,11 +128,11 @@ def crossCheckTest(SrcList, fdemType1, fdemType2, comp, addrandoms = False, useM
d2 = survey2.dpred(m) d2 = survey2.dpred(m)
if verbose: if verbose:
print ' Problem 2 solved' print(' Problem 2 solved')
r = d2-d1 r = d2-d1
l2r = l2norm(r) l2r = l2norm(r)
tol = np.max([TOL*(10**int(np.log10(0.5* (l2norm(d1) + l2norm(d2)) ))),FLR]) tol = np.max([TOL*(10**int(np.log10(0.5* (l2norm(d1) + l2norm(d2)) ))),FLR])
print l2norm(d1), l2norm(d2), l2r , tol, l2r < tol print(l2norm(d1), l2norm(d2), l2r , tol, l2r < tol)
return l2r < tol return l2r < tol
+12 -6
View File
@@ -1,7 +1,13 @@
import TDEM from __future__ import absolute_import
import FDEM from __future__ import unicode_literals
import Static from __future__ import print_function
import Base from __future__ import division
import Analytics from future import standard_library
import Utils standard_library.install_aliases()
from . import TDEM
from . import FDEM
from . import Static
from . import Base
from . import Analytics
from . import Utils
from scipy.constants import mu_0, epsilon_0 from scipy.constants import mu_0, epsilon_0
+15 -9
View File
@@ -1,7 +1,13 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
import SimPEG.DCIP as DC import SimPEG.EM.Static.DC as DC
def run(plotIt=False): def run(plotIt=True):
cs = 25. cs = 25.
hx = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)] hx = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)]
hy = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)] hy = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)]
@@ -21,15 +27,15 @@ def run(plotIt=False):
# ax.plot(xyz_rxP[:,0],xyz_rxP[:,1], 'w.') # ax.plot(xyz_rxP[:,0],xyz_rxP[:,1], 'w.')
# ax.plot(xyz_rxN[:,0],xyz_rxN[:,1], 'r.', ms = 3) # ax.plot(xyz_rxN[:,0],xyz_rxN[:,1], 'r.', ms = 3)
rx = DC.RxDipole(xyz_rxP, xyz_rxN) rx = DC.Rx.Dipole(xyz_rxP, xyz_rxN)
src = DC.SrcDipole([rx], [-200, 0, -12.5], [+200, 0, -12.5]) src = DC.Src.Dipole([rx], np.r_[-200, 0, -12.5], np.r_[+200, 0, -12.5])
survey = DC.SurveyDC([src]) survey = DC.Survey([src])
problem = DC.ProblemDC_CC(mesh) problem = DC.Problem3D_CC(mesh)
problem.pair(survey) problem.pair(survey)
try: try:
from pymatsolver import MumpsSolver from pymatsolver import MumpsSolver
problem.Solver = MumpsSolver problem.Solver = MumpsSolver
except Exception, e: except Exception as e:
pass pass
data = survey.dpred(sigma) data = survey.dpred(sigma)
@@ -61,8 +67,8 @@ def run(plotIt=False):
ax[0].set_title('Computed') ax[0].set_title('Computed')
plt.show() plt.show()
return np.linalg.norm(data-data_ana)/np.linalg.norm(data_ana) return np.linalg.norm(data-data_ana) / np.linalg.norm(data_ana)
if __name__ == '__main__': if __name__ == '__main__':
print run(plotIt=True) print(run())
+14 -6
View File
@@ -1,3 +1,11 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import Mesh, Utils, np, sp from SimPEG import Mesh, Utils, np, sp
import SimPEG.DCIP as DC import SimPEG.DCIP as DC
import time import time
@@ -57,7 +65,7 @@ def run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', u
model[ind] = sig[2] model[ind] = sig[2]
# Get index of the center # Get index of the center
indy = int(mesh.nCy/2) indy = int(mesh.nCy // 2)
# Plot the model for reference # Plot the model for reference
# Define core mesh extent # Define core mesh extent
@@ -124,10 +132,10 @@ def run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', u
tx = np.squeeze(Tx[ii][:,0:1]) tx = np.squeeze(Tx[ii][:,0:1])
tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2 tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2
inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T) inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T)
RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1] / mesh.vol[inds] ) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*([-1] / mesh.vol[inds])
else: else:
inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T ) inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T )
RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1,1] / mesh.vol[inds] ) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*([-1,1] / mesh.vol[inds])
# Iterative Solve # Iterative Solve
Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5) Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5)
@@ -143,10 +151,10 @@ def run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', u
dtemp = (P1*phi - P2*phi)*np.pi dtemp = (P1*phi - P2*phi)*np.pi
data.append( dtemp ) data.append( dtemp )
print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time), print('\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time), end=' ')
print 'Transmitter {0} of {1}'.format(ii,len(Tx)) print('Transmitter {0} of {1}'.format(ii,len(Tx)))
print 'Forward completed' print('Forward completed')
# Let's just convert the 3D format into 2D (distance along line) and plot # Let's just convert the 3D format into 2D (distance along line) and plot
survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc) , 'Xloc') survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc) , 'Xloc')
+7 -1
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
import SimPEG.EM as EM import SimPEG.EM as EM
from SimPEG.EM import mu_0 from SimPEG.EM import mu_0
@@ -56,7 +62,7 @@ def run(plotIt=True):
try: try:
from pymatsolver import MumpsSolver from pymatsolver import MumpsSolver
prb.Solver = MumpsSolver prb.Solver = MumpsSolver
except ImportError, e: except ImportError as e:
prb.Solver = SolverLU prb.Solver = SolverLU
prb.pair(survey) prb.pair(survey)
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
import SimPEG.EM as EM import SimPEG.EM as EM
+26 -16
View File
@@ -1,3 +1,10 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
from SimPEG.EM import FDEM, Analytics, mu_0 from SimPEG.EM import FDEM, Analytics, mu_0
import time import time
@@ -19,10 +26,13 @@ def run(plotIt=True):
Morrison Casing Model, and the results are used in a 2016 SEG abstract by Morrison Casing Model, and the results are used in a 2016 SEG abstract by
Yang et al. Yang et al.
- Schenkel, C.J., and H.F. Morrison, 1990, Effects of well casing on potential field measurements using downhole current sources: Geophysical prospecting, 38, 663-686. .. code-block:: text
Schenkel, C.J., and H.F. Morrison, 1990, Effects of well casing on potential field measurements using downhole current sources: Geophysical prospecting, 38, 663-686.
The model consists of: The model consists of:
- Air: Conductivity 1e-8 S/m, above z = 0 - Air: Conductivity 1e-8 S/m, above z = 0
- Background: conductivity 1e-2 S/m, below z = 0 - Background: conductivity 1e-2 S/m, below z = 0
- Casing: conductivity 1e6 S/m - Casing: conductivity 1e6 S/m
@@ -64,8 +74,8 @@ def run(plotIt=True):
casing_l = 300 # length of the casing casing_l = 300 # length of the casing
casing_r = 0.1 casing_r = 0.1
casing_a = casing_r - casing_t/2. # inner radius casing_a = casing_r - casing_t / 2. # inner radius
casing_b = casing_r + casing_t/2. # outer radius casing_b = casing_r + casing_t / 2. # outer radius
casing_z = np.r_[-casing_l,0.] casing_z = np.r_[-casing_l,0.]
@@ -75,25 +85,25 @@ def run(plotIt=True):
src_loc = np.r_[0.,0.,dsz] src_loc = np.r_[0.,0.,dsz]
inf_loc = np.r_[0.,0.,1e4] inf_loc = np.r_[0.,0.,1e4]
print 'Skin Depth: ', [(500./np.sqrt(sigmaback*_)) for _ in freqs] print('Skin Depth: ', [(500. / np.sqrt(sigmaback*_)) for _ in freqs])
# ------------------ MESH ------------------ # ------------------ MESH ------------------
# fine cells near well bore # fine cells near well bore
csx1, csx2 = 2e-3, 60. csx1, csx2 = 2e-3, 60.
pfx1, pfx2 = 1.3, 1.3 pfx1, pfx2 = 1.3, 1.3
ncx1 = np.ceil(casing_b/csx1+2) ncx1 = np.ceil(casing_b/csx1)+2
# pad nicely to second cell size # pad nicely to second cell size
npadx1 = np.floor(np.log(csx2/csx1) / np.log(pfx1)) npadx1 = np.log(csx2/csx1) // np.log(pfx1)
hx1a,hx1b = Utils.meshTensor([(csx1,ncx1)]),Utils.meshTensor([(csx1,npadx1,pfx1)]) hx1a,hx1b = Utils.meshTensor([(csx1,ncx1)]),Utils.meshTensor([(csx1,npadx1,pfx1)])
dx1 = sum(hx1a)+sum(hx1b) dx1 = sum(hx1a)+sum(hx1b)
dx1 = np.floor(dx1/csx2) dx1 = dx1 // csx2
hx1b *= (dx1*csx2 - sum(hx1a))/sum(hx1b) hx1b *= (dx1*csx2 - sum(hx1a)) / sum(hx1b)
# second chunk of mesh # second chunk of mesh
dx2 = 300. # uniform mesh out to here dx2 = 300. # uniform mesh out to here
ncx2 = np.ceil((dx2 - dx1)/csx2) ncx2 = np.ceil((dx2 - dx1) / csx2)
npadx2 = 45 npadx2 = 45
hx2a, hx2b = Utils.meshTensor([(csx2,ncx2)]), Utils.meshTensor([(csx2,npadx2,pfx2)]) hx2a, hx2b = Utils.meshTensor([(csx2,ncx2)]), Utils.meshTensor([(csx2,npadx2,pfx2)])
hx = np.hstack([hx1a,hx1b,hx2a,hx2b]) hx = np.hstack([hx1a,hx1b,hx2a,hx2b])
@@ -107,8 +117,8 @@ def run(plotIt=True):
# Mesh # Mesh
mesh = Mesh.CylMesh([hx,1.,hz], [0.,0.,-np.sum(hz[:npadzu+ncz-nza])]) mesh = Mesh.CylMesh([hx,1.,hz], [0.,0.,-np.sum(hz[:npadzu+ncz-nza])])
print 'Mesh Extent xmax: %f,: zmin: %f, zmax: %f'%(mesh.vectorCCx.max(), mesh.vectorCCz.min(), mesh.vectorCCz.max()) print('Mesh Extent xmax: %f,: zmin: %f, zmax: %f'%(mesh.vectorCCx.max(), mesh.vectorCCz.min(), mesh.vectorCCz.max()))
print 'Number of cells', mesh.nC print('Number of cells', mesh.nC)
if plotIt is True: if plotIt is True:
fig, ax = plt.subplots(1, 1, figsize=(6, 4)) fig, ax = plt.subplots(1, 1, figsize=(6, 4))
@@ -215,13 +225,13 @@ def run(plotIt=True):
# ------------ Problem and Survey --------------- # ------------ Problem and Survey ---------------
survey = FDEM.Survey(sg_p + dg_p) survey = FDEM.Survey(sg_p + dg_p)
mapping = [('sigma', Maps.IdentityMap(mesh))] mapping = [('sigma', Maps.IdentityMap(mesh))]
problem = FDEM.Problem3D_h(mesh, mapping=mapping) problem = FDEM.Problem3D_h(mesh, mapping=mapping, Solver=solver)
problem.pair(survey) problem.pair(survey)
# ------------- Solve --------------------------- # ------------- Solve ---------------------------
t0 = time.time() t0 = time.time()
fieldsCasing = problem.fields(sigCasing) fieldsCasing = problem.fields(sigCasing)
print 'Time to solve 2 sources', time.time() - t0 print('Time to solve 2 sources', time.time() - t0)
# Plot current # Plot current
@@ -248,9 +258,9 @@ def run(plotIt=True):
in1_in = in1[np.r_[inds]] in1_in = in1[np.r_[inds]]
z_in = mesh.gridFz[inds_fz,2] z_in = mesh.gridFz[inds_fz,2]
in0_in = in0_in.reshape([in0_in.shape[0]/3,3]) in0_in = in0_in.reshape([in0_in.shape[0]//3,3])
in1_in = in1_in.reshape([in1_in.shape[0]/3,3]) in1_in = in1_in.reshape([in1_in.shape[0]//3,3])
z_in = z_in.reshape([z_in.shape[0]/3,3]) z_in = z_in.reshape([z_in.shape[0]//3,3])
I0 = in0_in.sum(1).real I0 = in0_in.sum(1).real
I1 = in1_in.sum(1).real I1 = in1_in.sum(1).real
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
import SimPEG.EM as EM import SimPEG.EM as EM
from SimPEG.EM import mu_0 from SimPEG.EM import mu_0
@@ -1,3 +1,9 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
from SimPEG.FLOW import Richards from SimPEG.FLOW import Richards
+17 -31
View File
@@ -1,3 +1,11 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import range
from SimPEG import * from SimPEG import *
@@ -42,62 +50,40 @@ def run(N=100, plotIt=True):
survey = Survey.LinearSurvey() survey = Survey.LinearSurvey()
survey.pair(prob) survey.pair(prob)
survey.dobs = prob.fields(mtrue) + std_noise * np.random.randn(nk) survey.dobs = prob.fields(mtrue) + std_noise * np.random.randn(nk)
#survey.makeSyntheticData(mtrue, std=std_noise)
wd = np.ones(nk) * std_noise wd = np.ones(nk) * std_noise
#print survey.std[0]
#M = prob.mesh
# Distance weighting # Distance weighting
wr = np.sum(prob.G**2.,axis=0)**0.5 wr = np.sum(prob.G**2.,axis=0)**0.5
wr = ( wr/np.max(wr) ) wr = ( wr/np.max(wr))
# reg = Regularization.Simple(mesh)
# reg.mref = mref
# reg.cell_weights = wr
#
dmis = DataMisfit.l2_DataMisfit(survey) dmis = DataMisfit.l2_DataMisfit(survey)
dmis.Wd = 1./wd dmis.Wd = 1./wd
#
# opt = Optimization.ProjectedGNCG(maxIter=20,lower=-2.,upper=2., maxIterCG= 10, tolCG = 1e-4)
# invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
# invProb.curModel = m0
#
# beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
# target = Directives.TargetMisfit()
#
betaest = Directives.BetaEstimate_ByEig() betaest = Directives.BetaEstimate_ByEig()
# inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest, target])
#
#
# mrec = inv.run(m0)
# ml2 = mrec
# print "Final misfit:" + str(invProb.dmisfit.eval(mrec))
#
# # Switch regularization to sparse
# phim = invProb.phi_m_last
# phid = invProb.phi_d
reg = Regularization.Sparse(mesh) reg = Regularization.Sparse(mesh)
reg.mref = mref reg.mref = mref
reg.cell_weights = wr reg.cell_weights = wr
reg.mref = np.zeros(mesh.nC) reg.mref = np.zeros(mesh.nC)
eps_p = 5e-2
eps_q = 5e-2
norms = [0., 0., 2., 2.]
opt = Optimization.ProjectedGNCG(maxIter=100 ,lower=-2.,upper=2., maxIterLS = 20, maxIterCG= 10, tolCG = 1e-3) opt = Optimization.ProjectedGNCG(maxIter=100 ,lower=-2.,upper=2., maxIterLS = 20, maxIterCG= 10, tolCG = 1e-3)
invProb = InvProblem.BaseInvProblem(dmis, reg, opt) invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
update_Jacobi = Directives.Update_lin_PreCond() update_Jacobi = Directives.Update_lin_PreCond()
IRLS = Directives.Update_IRLS( norms=norms, eps_p=eps_p, eps_q=eps_q)
# Set the IRLS directive, penalize the lowest 25 percentile of model values
# Start with an l2-l2, then switch to lp-norms
norms = [0., 0., 2., 2.]
IRLS = Directives.Update_IRLS( norms=norms, prctile = 25, maxIRLSiter = 15, minGNiter=3)
inv = Inversion.BaseInversion(invProb, directiveList=[IRLS,betaest,update_Jacobi]) inv = Inversion.BaseInversion(invProb, directiveList=[IRLS,betaest,update_Jacobi])
# Run inversion # Run inversion
mrec = inv.run(m0) mrec = inv.run(m0)
print "Final misfit:" + str(invProb.dmisfit.eval(mrec)) print("Final misfit:" + str(invProb.dmisfit.eval(mrec)))
if plotIt: if plotIt:
+7
View File
@@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
+30 -30
View File
@@ -1,15 +1,19 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
import SimPEG as simpeg import SimPEG as simpeg
import numpy as np import numpy as np
from SimPEG import NSEM import SimPEG.MT as MT
from scipy.constants import mu_0 from scipy.constants import mu_0
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
np.random.seed(1983)
def run(plotIt=True): def run(plotIt=True):
""" """
MT: 1D: Inversion MT: 1D: Inversion
======================= =================
Forward model 1D MT data. Forward model 1D MT data.
Setup and run a MT 1D inversion. Setup and run a MT 1D inversion.
@@ -19,13 +23,13 @@ def run(plotIt=True):
## Setup the forward modeling ## Setup the forward modeling
# Setting up 1D mesh and conductivity models to forward model data. # Setting up 1D mesh and conductivity models to forward model data.
# Frequency # Frequency
nFreq = 26 nFreq = 31
freqs = np.logspace(2,-3,nFreq) freqs = np.logspace(3,-3,nFreq)
# Set mesh parameters # Set mesh parameters
ct = 10 ct = 20
air = simpeg.Utils.meshTensor([(ct,25,1.4)]) air = simpeg.Utils.meshTensor([(ct,16,1.4)])
core = np.concatenate( ( np.kron(simpeg.Utils.meshTensor([(ct,10,-1.3)]),np.ones((5,))) , simpeg.Utils.meshTensor([(ct,5)]) ) ) core = np.concatenate( ( np.kron(simpeg.Utils.meshTensor([(ct,10,-1.3)]),np.ones((5,))) , simpeg.Utils.meshTensor([(ct,5)]) ) )
bot = simpeg.Utils.meshTensor([(core[0],25,-1.4)]) bot = simpeg.Utils.meshTensor([(core[0],10,-1.4)])
x0 = -np.array([np.sum(np.concatenate((core,bot)))]) x0 = -np.array([np.sum(np.concatenate((core,bot)))])
# Make the model # Make the model
m1d = simpeg.Mesh.TensorMesh([np.concatenate((bot,core,air))], x0=x0) m1d = simpeg.Mesh.TensorMesh([np.concatenate((bot,core,air))], x0=x0)
@@ -35,7 +39,7 @@ def run(plotIt=True):
layer1 = (m1d.vectorCCx<-500.) & (m1d.vectorCCx>=-800.) layer1 = (m1d.vectorCCx<-500.) & (m1d.vectorCCx>=-800.)
layer2 = (m1d.vectorCCx<-3500.) & (m1d.vectorCCx>=-5000.) layer2 = (m1d.vectorCCx<-3500.) & (m1d.vectorCCx>=-5000.)
# Set the conductivity values # Set the conductivity values
sig_half = 1e-2 sig_half = 2e-3
sig_air = 1e-8 sig_air = 1e-8
sig_layer1 = .2 sig_layer1 = .2
sig_layer2 = .2 sig_layer2 = .2
@@ -59,31 +63,31 @@ def run(plotIt=True):
# Receivers # Receivers
rxList = [] rxList = []
for rxType in ['z1dr','z1di']: for rxType in ['z1dr','z1di']:
rxList.append(NSEM.Rx(simpeg.mkvc(np.array([-0.5]),2).T,rxType)) rxList.append(MT.Rx(simpeg.mkvc(np.array([0.0]),2).T,rxType))
# Source list # Source list
srcList =[] srcList =[]
for freq in freqs: for freq in freqs:
srcList.append(NSEM.SrcNSEM.polxy_1Dprimary(rxList,freq)) srcList.append(MT.SrcMT.polxy_1Dprimary(rxList,freq))
# Make the survey # Make the survey
survey = NSEM.Survey(srcList) survey = MT.Survey(srcList)
survey.mtrue = m_true survey.mtrue = m_true
## Set the problem ## Set the problem
problem = NSEM.Problem1D_ePrimSec(m1d,sigmaPrimary=sigma_0,mapping=mappingExpAct) problem = MT.Problem1D.eForm_psField(m1d,sigmaPrimary=sigma_0,mapping=mappingExpAct)
problem.pair(survey) problem.pair(survey)
## Forward model data ## Forward model data
# Project the data # Project the data
survey.dtrue = survey.dpred(m_true) survey.dtrue = survey.dpred(m_true)
survey.dobs = survey.dtrue + 0.01*abs(survey.dtrue)*np.random.randn(*survey.dtrue.shape) survey.dobs = survey.dtrue + 0.025*abs(survey.dtrue)*np.random.randn(*survey.dtrue.shape)
if plotIt: if plotIt:
fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem,[]) fig = MT.Utils.dataUtils.plotMT1DModelData(problem, [m_0])
fig.suptitle('Target - smooth true') fig.suptitle('Target - smooth true')
# Assign uncertainties # Assign uncertainties
std = 0.025 # 5% std std = 0.05 # 5% std
survey.std = np.abs(survey.dobs*std) survey.std = np.abs(survey.dobs*std)
# Assign the data weight # Assign the data weight
Wd = 1./survey.std Wd = 1./survey.std
@@ -92,33 +96,30 @@ def run(plotIt=True):
# Define a counter # Define a counter
C = simpeg.Utils.Counter() C = simpeg.Utils.Counter()
# Set the optimization # Set the optimization
opt = simpeg.Optimization.ProjectedGNCG(maxIter = 25) opt = simpeg.Optimization.InexactGaussNewton(maxIter = 30)
opt.counter = C opt.counter = C
opt.lower = np.log(1e-4) opt.LSshorten = 0.5
opt.upper = np.log(5)
opt.LSshorten = 0.1
opt.remember('xc') opt.remember('xc')
# Data misfit # Data misfit
dmis = simpeg.DataMisfit.l2_DataMisfit(survey) dmis = simpeg.DataMisfit.l2_DataMisfit(survey)
dmis.Wd = Wd dmis.Wd = Wd
# Regularization - with a regularization mesh # Regularization - with a regularization mesh
regMesh = simpeg.Mesh.TensorMesh([m1d.hx[active]],m1d.x0) regMesh = simpeg.Mesh.TensorMesh([m1d.hx[problem.mapping.sigmaMap.maps[-1].indActive]],m1d.x0)
reg = simpeg.Regularization.Tikhonov(regMesh) reg = simpeg.Regularization.Tikhonov(regMesh)
reg.mrefInSmooth = True reg.mrefInSmooth = True
reg.alpha_s = 1e-1 reg.alpha_s = 1e-7
reg.alpha_x = 1. reg.alpha_x = 1.
# Inversion problem # Inversion problem
invProb = simpeg.InvProblem.BaseInvProblem(dmis, reg, opt) invProb = simpeg.InvProblem.BaseInvProblem(dmis, reg, opt)
invProb.counter = C invProb.counter = C
# Beta cooling # Beta cooling
beta = simpeg.Directives.BetaSchedule() beta = simpeg.Directives.BetaSchedule()
beta.coolingRate = 4. beta.coolingRate = 4
beta.coolingFactor = 4. betaest = simpeg.Directives.BetaEstimate_ByEig(beta0_ratio=0.75)
betaest = simpeg.Directives.BetaEstimate_ByEig(beta0_ratio=1.)
betaest.beta0 = 1.
targmis = simpeg.Directives.TargetMisfit() targmis = simpeg.Directives.TargetMisfit()
targmis.target = survey.nD targmis.target = survey.nD
saveModel = simpeg.Directives.SaveModelEveryIteration()
saveModel.fileName = 'Inversion_TargMisEqnD_smoothTrue'
# Create an inversion object # Create an inversion object
inv = simpeg.Inversion.BaseInversion(invProb, directiveList=[beta,betaest,targmis]) inv = simpeg.Inversion.BaseInversion(invProb, directiveList=[beta,betaest,targmis])
@@ -126,9 +127,8 @@ def run(plotIt=True):
mopt = inv.run(m_0) mopt = inv.run(m_0)
if plotIt: if plotIt:
fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem,[mopt]) fig = MT.Utils.dataUtils.plotMT1DModelData(problem,[mopt])
fig.suptitle('Target - smooth true') fig.suptitle('Target - smooth true')
fig.axes[0].set_ylim([-10000,500])
plt.show() plt.show()
if __name__ == '__main__': if __name__ == '__main__':
@@ -1,428 +0,0 @@
from scipy.constants import epsilon_0, mu_0
import matplotlib.pyplot as plt
import numpy as np
from ipywidgets import *
from SimPEG.EM.Utils import k, omega
"""
MT1D: n layered earth problem
*****************************
Author: Thibaut Astic
Contact: thast@eos.ubc.ca
Date: January 2016
This code compute the analytic response of a n-layered Earth to a plane wave (Magneto-Tellurics).
We start by looking at Maxwell's equations in the electric
field \\\(\\\mathbf{E}\\) and the magnetic flux
\\\(\\\mathbf{H}\\) to write the wave equations
\\(\\ \nabla ^2 \mathbf{E_x} + k^2 \mathbf{E_x} = 0 \\) &
\\(\\ \nabla ^2 \mathbf{H_y} + k^2 \mathbf{H_y} = 0 \\)
Then solving the equations in each layer "j" between z_{j-1} and z_j in the form of
\\(\\ E_{x,j} (z) = U_j e^{i k (z-z_{j-1})} + D_j e^{-i k (z-z_{j-1})} \\)
\\(\\ H_{y,j} (z) = \frac{1}{Z_j} (D_j e^{-i k (z-z_{j-1})} - U_j e^{i k (z-z_{j-1})}) \\)
With U and D the Up and Down components of the E-field.
The iteration from one layer to another is ensure by:
\\(\\ \left(\begin{matrix} E_{x,j} \\ H_{y,j} \end{matrix} \right) =
P_j T_j P^{-1}_J \left(\begin{matrix} E_{x,j+1} \\ H_{y,j+1} \end{matrix} \right) \\)
And the Boundary Condition is set for the E-field in the last layer, with no Up component (=0)
and only a down component (=1 then normalized by the highest amplitude to ensure numeric stability)
The layer 0 is assumed to be the air layer.
"""
#Define a frquency range for a survey
frange = lambda minfreq, maxfreq, step: np.logspace(minfreq,maxfreq,num = step, base = 10.)
#Functions to create random physical Perties for a n-layered earth
thick = lambda minthick, maxthick, nlayer: np.append(np.array([1.2*10.**5]),
np.ndarray.round(minthick + (maxthick-minthick)* np.random.rand(nlayer-1,1)
,decimals =1))
sig = lambda minsig, maxsig, nlayer: np.append(np.array([0.]),
np.ndarray.round(10.**minsig + (10.**maxsig-10.**minsig)* np.random.rand(nlayer,1)
,decimals=3))
mu = lambda minmu, maxmu, nlayer: np.append(np.array([1.]),
np.ndarray.round(minmu + (maxmu-minmu)* np.random.rand(nlayer,1)
,decimals=1))
eps = lambda mineps, maxeps, nlayer: np.append(np.array([1.]),
np.ndarray.round(mineps + (maxeps-mineps)* np.random.rand(nlayer,1)
,decimals=1))
#Evaluate Impedance Z of a layer
ImpZ = lambda f, mu, k: omega(f)*mu*mu_0/k
#Complex Cole-Cole Conductivity - EM utils
PCC= lambda siginf,m,t,c,f: siginf*(1.-(m/(1.+(1j*omega(f)*t)**c)))
#Converted thickness array into top of layer array
top = lambda thick: np.cumsum(thick)
#Propagation Matrix and theirs inverses
#matrix T for transition of Up and Down components accross a layer
T = lambda h,k: np.matrix([[np.exp(1j*k*h),0.],[0.,np.exp(-1j*k*h)]],dtype='complex_')
Tinv = lambda h,k: np.matrix([[np.exp(-1j*k*h),0.],[0.,np.exp(1j*k*h)]],dtype='complex_')
#transition of Up and Down components accross a layer
UD_Z = lambda UD,z,zj,k : T((z-zj),k)*UD
#matrix P relating Up and Down components with E and H fields
P = lambda z: np.matrix([[1.,1,],[-1./z,1./z]],dtype='complex_')
Pinv = lambda z: np.matrix([[1.,-z],[1.,z]],dtype='complex_')/2.
#Time Variation of E and H
E_ZT = lambda U,D,f,t : np.exp(1j*omega(f)*t)*(U+D)
H_ZT = lambda U,D,Z,f,t : (1./Z)*np.exp(1j*omega(f)*t)*(D-U)
#Plot the configuration of the problem
def PlotConfiguration(thick,sig,eps,mu,ax,widthg,z):
topn = top(thick)
widthn = np.arange(-widthg,widthg+widthg/10.,widthg/10.)
ax.set_ylim([z.min(),z.max()])
ax.set_xlim([-widthg,widthg])
ax.set_ylabel("Depth (m)", fontsize=16.)
ax.yaxis.tick_right()
ax.yaxis.set_label_position("right")
#define filling for the different layers
hatches=['/' , '+', 'x', '|' , '\\', '-' , 'o' , 'O' , '.' , '*' ]
#Write the physical properties of air
ax.annotate(("Air, $\sigma$ =%1.0f mS/m")%(sig[0]*10**(3)),
xy=(-widthg/2., -np.abs(z.max())/2.), xycoords='data',
xytext=(-widthg/2., -np.abs(z.max())/2.), textcoords='data',
fontsize=14.)
ax.annotate(("$\epsilon_r$= %1i")%(eps[0]),
xy=(-widthg/2., -np.abs(z.max())/3.), xycoords='data',
xytext=(-widthg/2., -np.abs(z.max())/3.), textcoords='data',
fontsize=14.)
ax.annotate(("$\mu_r$= %1i")%(mu[0]),
xy=(-widthg/2., -np.abs(z.max())/3.), xycoords='data',
xytext=(0, -np.abs(z.max())/3.), textcoords='data',
fontsize=14.)
#Write the physical properties of the differents layers up to the (n-1)-th and fill it with pattern
for i in range(1,len(topn)-1,1):
if topn[i] == topn[i+1]:
pass
else:
ax.annotate(("$\sigma$ =%3.3f mS/m")%(sig[i]*10**(3)),
xy=(0., (2.*topn[i]+topn[i+1])/3), xycoords='data',
xytext=(0., (2.*topn[i]+topn[i+1])/3), textcoords='data',
fontsize=14.)
ax.annotate(("$\epsilon_r$= %1i")%(eps[i]),
xy=(-widthg/1.1, (2.*topn[i]+topn[i+1])/3), xycoords='data',
xytext=(-widthg/1.1, (2.*topn[i]+topn[i+1])/3), textcoords='data',
fontsize=14.)
ax.annotate(("$\mu_r$= %1.2f")%(mu[i]),
xy=(-widthg/2., (2.*topn[i]+topn[i+1])/3), xycoords='data',
xytext=(-widthg/2., (2.*topn[i]+topn[i+1])/3), textcoords='data',
fontsize=14.)
ax.plot(widthn,topn[i]*np.ones_like(widthn),color='black')
ax.fill_between(widthn,topn[i],topn[i+1],alpha=0.3,color="none",edgecolor='black', hatch=hatches[(i-1)%10])
#Write the physical properties of the n-th layer and fill it with pattern
ax.plot(widthn,topn[-1]*np.ones_like(widthn),color='black')
ax.fill_between(widthn,topn[-1],z.max(),alpha=0.3,color="none",edgecolor='black', hatch=hatches[(len(topn)-2)%10])
ax.annotate(("$\sigma$ =%3.3f mS/m")%(sig[-1]*10**(3)),
xy=(0., (2.*topn[-1]+z.max())/3), xycoords='data',
xytext=(0., (2.*topn[-1]+z.max())/3), textcoords='data',
fontsize=14.)
ax.annotate(("$\epsilon_r$= %1i")%(eps[-1]),
xy=(-widthg/1.1, (2.*topn[-1]+z.max())/3), xycoords='data',
xytext=(-widthg/1.1, (2.*topn[-1]+z.max())/3), textcoords='data',
fontsize=14.)
ax.annotate(("$\mu_r$= %1.2f")%(mu[-1]),
xy=(-widthg/2., (2.*topn[-1]+z.max())/3), xycoords='data',
xytext=(-widthg/2., (2.*topn[-1]+z.max())/3), textcoords='data',
fontsize=14.)
#plot Trees!
ax.annotate("",
xy=(widthg/2., -1.*z.max()/5.), xycoords='data',
xytext=(widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.2,head_length=1.2',color='green',linewidth=2.)
)
ax.annotate("",
xy=(widthg/2., -3./4.*z.max()/5.), xycoords='data',
xytext=(widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.4,head_length=1.4',color='green',linewidth=2.)
)
ax.annotate("",
xy=(widthg/2., -1./2.*z.max()/5.), xycoords='data',
xytext=(widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.6,head_length=1.6',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.2*widthg/2., -1.*z.max()/5.), xycoords='data',
xytext=(1.2*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.2,head_length=1.2',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.2*widthg/2., -3./4.*z.max()/5.), xycoords='data',
xytext=(1.2*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.4,head_length=1.4',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.2*widthg/2., -1./2.*z.max()/5.), xycoords='data',
xytext=(1.2*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.6,head_length=1.6',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.5*widthg/2., -1.*z.max()/5.), xycoords='data',
xytext=(1.5*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.2,head_length=1.2',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.5*widthg/2., -3./4.*z.max()/5.), xycoords='data',
xytext=(1.5*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.4,head_length=1.4',color='green',linewidth=2.)
)
ax.annotate("",
xy=(1.5*widthg/2., -1./2.*z.max()/5.), xycoords='data',
xytext=(1.5*widthg/2., 0.), textcoords='data',
arrowprops=dict(arrowstyle='->, head_width=1.6,head_length=1.6',color='green',linewidth=2.)
)
ax.invert_yaxis()
return ax
#Propagate Up and Down component for a certain frequency & evaluate E and H field
def Propagate(f,H,sig,chg,taux,c,mu,eps,n):
sigcm = np.zeros_like(sig,dtype='complex_')
for j in range(1,len(sig)):
sigcm[j]=PCC(sig[j],chg[j],taux[j],c[j],f)
K = k(f, sigcm, mu, eps)
Z = ImpZ(f,mu,K)
EH = np.matrix(np.zeros((2,n+1),dtype = 'complex_'),dtype = 'complex_')
UD = np.matrix(np.zeros((2,n+1),dtype = 'complex_'),dtype = 'complex_')
UD[1,-1] = 1.
for i in range(-2,-(n+2),-1):
UD[:,i] = Tinv(H[i+1],K[i])*Pinv(Z[i])*P(Z[i+1])*UD[:,i+1]
UD = UD/((np.abs(UD[0,:]+UD[1,:])).max())
for j in range(0,n+1):
EH[:,j] = np.matrix([[1.,1,],[-1./Z[j],1./Z[j]]])*UD[:,j]
return UD, EH, Z ,K
#Evaluate the apparent resistivity and phase for a frequency range
def appres(F,H,sig,chg,taux,c,mu,eps,n):
Res = np.zeros_like(F)
Phase = np.zeros_like(F)
App_ImpZ= np.zeros_like(F,dtype='complex_')
for i in range(0,len(F)):
UD,EH,Z ,K = Propagate(F[i],H,sig,chg,taux,c,mu,eps,n)
App_ImpZ[i] = EH[0,1]/EH[1,1]
Res[i] = np.abs(App_ImpZ[i])**2./(mu_0*omega(F[i]))
Phase[i] = np.angle(App_ImpZ[i], deg = True)
return Res,Phase
#Evaluate Up, Down components, E and H field, for a frequency range,
#a discretized depth range and a time range (use to calculate envelope)
def calculateEHzt(F,H,sig,chg,taux,c,mu,eps,n,zsample,tsample):
topc = top(H)
layer = np.zeros(len(zsample),dtype=np.int)-1
Exzt = np.matrix(np.zeros((len(zsample),len(tsample)),dtype = 'complex_'),dtype = 'complex_')
Hyzt = np.matrix(np.zeros((len(zsample),len(tsample)),dtype = 'complex_'),dtype = 'complex_')
Uz = np.matrix(np.zeros((len(zsample),len(tsample)),dtype = 'complex_'),dtype = 'complex_')
Dz = np.matrix(np.zeros((len(zsample),len(tsample)),dtype = 'complex_'),dtype = 'complex_')
UDaux = np.matrix(np.zeros((2,len(zsample)),dtype = 'complex_'),dtype = 'complex_')
for i in range(0,n+1,1):
layer = layer+(zsample>=topc[i])*1
for j in range(0,len(F)):
UD,EH,Z ,K = Propagate(F[j],H,sig,chg,taux,c,mu,eps,n)
for p in range(0,len(zsample)):
UDaux[:,p] = UD_Z(UD[:,layer[p]],zsample[p],topc[layer[p]],K[layer[p]])
for q in range(0,len(tsample)):
Exzt[p,q] = Exzt[p,q] + E_ZT(UDaux[0,p],UDaux[1,p],F[j],tsample[q])/len(F)
Hyzt[p,q] = Hyzt[p,q] + H_ZT(UDaux[0,p],UDaux[1,p],Z[layer[p]],F[j],tsample[q])/len(F)
Uz[p,q] = Uz[p,q] + UDaux[0,p]*np.exp(1j*omega(F[j])*tsample[q])/len(F)
Dz[p,q] = Dz[p,q] + UDaux[1,p]*np.exp(1j*omega(F[j])*tsample[q])/len(F)
return Exzt,Hyzt,Uz,Dz,UDaux,layer
#Function to Plot Apparent Resistivity and Phase
def PlotAppRes(F,H,sig,chg,taux,c,mu,eps,n,fenvelope,PlotEnvelope):
Res, Phase = appres(F,H,sig,chg,taux,c,mu,eps,n)
fig,ax = plt.subplots(1,2,figsize=(16,10))
ax[0].scatter(Res,F,color='black')
ax[0].set_xscale('Log')
ax[0].set_yscale('Log')
ax[0].set_xlim([10.**(np.log10(Res.min())-1.),10.**(np.log10(Res.max())+1.)])
ax[0].set_ylim([F.min(),F.max()])
ax[0].set_xlabel('Apparent Resistivity (Ohm*m)',fontsize=16.,color="black")
ax[0].set_ylabel('Frequency (Hz)',fontsize=16.)
ax[0].grid(which='major')
ax0 = ax[0].twiny()
ax0.set_xlim([0.,90.])
ax0.set_ylim([F.min(),F.max()])
ax0.scatter(Phase,F,color='purple')
ax0.set_xlabel('Phase (Degrees)',fontsize=16.,color="purple")
zc=np.arange(-(H[1:].max()+10)*n,(H[1:].max()+10)*n,10.)
ax[0].tick_params(labelsize=16)
ax[1].tick_params(labelsize=16)
ax0.tick_params(labelsize=16)
if PlotEnvelope:
widthn=np.logspace(np.log10(Res.min())-1., np.log10(Res.max())+1., num=100, endpoint=True, base=10.0)
fenvelope1n=np.ones(100)*fenvelope
ax[0].plot(widthn,fenvelope1n,linestyle='dashed',color='black')
tc=np.arange(0.,1./fenvelope,0.01/(fenvelope))
Exzt,Hyzt,Uz,Dz,UDaux,layer = calculateEHzt(np.array([fenvelope]),H,sig,chg,taux,c,mu,eps,n,zc,tc)
ax1=ax[1].twiny()
ax[1].tick_params(labelsize=16)
ax1.tick_params(labelsize=16)
ax[1].set_xlabel('Amplitude Electric Field E (V/m)',color='blue',fontsize=16)
ax1.set_xlabel('Amplitude Magnetic Field H (A/m)',color='red',fontsize=16)
ax[1].fill_betweenx(zc,np.squeeze(np.asarray(np.real(Exzt.min(axis=1)))),
np.squeeze(np.asarray(np.real(Exzt.max(axis=1)))),
color='blue', alpha=0.1)
ax1.fill_betweenx(zc,np.squeeze(np.asarray(np.real(Hyzt.min(axis=1)))),
np.squeeze(np.asarray(np.real(Hyzt.max(axis=1)))),
color='red', alpha=0.1)
ax[1] = PlotConfiguration(H,sig,eps,mu,ax[1],(1.5*np.abs(Exzt).max()),zc)
ax1.set_xlim([-1.5*np.abs(Hyzt).max(),1.5*np.abs(Hyzt).max()])
ax1.set_xlim([-1.5*np.abs(Hyzt).max(),1.5*np.abs(Hyzt).max()])
else:
print 'No envelop (if True, might be slow)'
ax[1] = PlotConfiguration(H,sig,eps,mu,ax[1],1.,zc)
ax[1].get_xaxis().set_ticks([])
plt.show()
#Interactive MT for Notebook
def PlotAppRes3LayersInteract(h1,h2,sigl1,sigl2,sigl3,mul1,mul2,mul3,epsl1,epsl2,epsl3,PlotEnvelope,F_Envelope):
frangn=frange(-5,5,100.)
sig3= np.array([0.,0.001,0.1, 0.001])
thick3 = np.array([120000.,50.,50.])
eps3=np.array([1.,1.,1.,1])
mu3=np.array([1.,1.,1.,1])
chg3=np.array([0.,0.1,0.,0.2])
chg3_0=np.array([0.,0.1,0.,0.])
taux3=np.array([0.,0.1,0.,0.1])
c3=np.array([1.,1.,1.,1.])
sig3[1]=sigl1
sig3[1]=10.**sig3[1]
sig3[2]=sigl2
sig3[2]=10.**sig3[2]
sig3[3]=sigl3
sig3[3]=10.**sig3[3]
mu3[1]=mul1
mu3[2]=mul2
mu3[3]=mul3
eps3[1]=epsl1
eps3[2]=epsl2
eps3[3]=epsl3
thick3[1]=h1
thick3[2]=h2
PlotAppRes(frangn,thick3,sig3,chg3_0,taux3,c3,mu3,eps3,3,F_Envelope,PlotEnvelope)
def run(n=3,plotIt=True):
# something to make a plot
F = frange(-5.,5.,20)
H = thick(50.,100.,n)
sign = sig(-5.,0.,n)
mun = mu(1.,2.,n)
epsn = eps(1.,9.,n)
chg = np.zeros_like(sign)
taux = np.zeros_like(sign)
c = np.zeros_like(sign)
Res, Phase = appres(F,H,sign,chg,taux,c,mun,epsn,n)
if plotIt:
PlotAppRes(F, H, sign, chg, taux, c, mun, epsn, n, fenvelope=1000., PlotEnvelope=True)
return Res, Phase
if __name__ == '__main__':
run()
+13 -8
View File
@@ -1,8 +1,14 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
# Test script to use SimPEG.MT platform to forward model synthetic data. # Test script to use SimPEG.MT platform to forward model synthetic data.
# Import # Import
import SimPEG as simpeg import SimPEG as simpeg
from SimPEG import NSEM from SimPEG import MT
import numpy as np import numpy as np
try: try:
from pymatsolver import MumpsSolver as Solver from pymatsolver import MumpsSolver as Solver
@@ -12,7 +18,7 @@ except:
def run(plotIt=True, nFreq=1): def run(plotIt=True, nFreq=1):
""" """
MT: 3D: Forward MT: 3D: Forward
======================= ===============
Forward model 3D MT data. Forward model 3D MT data.
@@ -37,25 +43,24 @@ def run(plotIt=True, nFreq=1):
for loc in rx_loc: for loc in rx_loc:
# NOTE: loc has to be a (1,3) np.ndarray otherwise errors accure # NOTE: loc has to be a (1,3) np.ndarray otherwise errors accure
for rxType in ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi','tzxr','tzxi','tzyr','tzyi']: for rxType in ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi','tzxr','tzxi','tzyr','tzyi']:
rxList.append(NSEM.Rx(simpeg.mkvc(loc,2).T,rxType)) rxList.append(MT.Rx(simpeg.mkvc(loc,2).T,rxType))
# Source list # Source list
srcList =[] srcList =[]
for freq in np.logspace(3,-3,nFreq): for freq in np.logspace(3,-3,nFreq):
srcList.append(NSEM.SrcNSEM.polxy_1Dprimary(rxList,freq)) srcList.append(MT.SrcMT.polxy_1Dprimary(rxList,freq))
# Survey MT # Survey MT
survey = NSEM.Survey(srcList) survey = MT.Survey(srcList)
## Setup the problem object ## Setup the problem object
problem = NSEM.Problem3D_ePrimSec(M, sigmaPrimary=sigBG) problem = MT.Problem3D.eForm_ps(M, sigmaPrimary=sigBG, Solver=Solver)
problem.pair(survey) problem.pair(survey)
problem.Solver = Solver
# Calculate the data # Calculate the data
fields = problem.fields(sig) fields = problem.fields(sig)
dataVec = survey.eval(fields) dataVec = survey.eval(fields)
# Make the data # Make the data
mtData = NSEM.Data(survey,dataVec) mtData = MT.Data(survey, dataVec)
# Add plots # Add plots
if plotIt: if plotIt:
pass pass
+69
View File
@@ -0,0 +1,69 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from builtins import dict
from future import standard_library
standard_library.install_aliases()
from SimPEG import Mesh, Maps, np
def run(plotIt=True):
"""
Maps: ComboMaps
===============
We will use an example where we want a 1D layered earth as
our model, but we want to map this to a 2D discretization to do our forward
modeling. We will also assume that we are working in log conductivity still,
so after the transformation we want to map to conductivity space.
To do this we will introduce the vertical 1D map (:class:`SimPEG.Maps.SurjectVertical1D`),
which does the first part of what we just described. The second part will be
done by the :class:`SimPEG.Maps.ExpMap` described above.
.. code-block:: python
:linenos:
M = Mesh.TensorMesh([7,5])
v1dMap = Maps.SurjectVertical1D(M)
expMap = Maps.ExpMap(M)
myMap = expMap * v1dMap
m = np.r_[0.2,1,0.1,2,2.9] # only 5 model parameters!
sig = myMap * m
If you noticed, it was pretty easy to combine maps. What is even cooler is
that the derivatives also are made for you (if everything goes right).
Just to be sure that the derivative is correct, you should always run the test
on the mapping that you create.
"""
M = Mesh.TensorMesh([7,5])
v1dMap = Maps.SurjectVertical1D(M)
expMap = Maps.ExpMap(M)
myMap = expMap * v1dMap
m = np.r_[0.2,1,0.1,2,2.9] # only 5 model parameters!
sig = myMap * m
if not plotIt: return
import matplotlib.pyplot as plt
figs, axs = plt.subplots(1,2)
axs[0].plot(m, M.vectorCCy, 'b-o')
axs[0].set_title('Model')
axs[0].set_ylabel('Depth, y')
axs[0].set_xlabel('Value, $m_i$')
axs[0].set_xlim(0,3)
axs[0].set_ylim(0,1)
clbar = plt.colorbar(M.plotImage(sig,ax=axs[1],grid=True,gridOpts=dict(color='grey'))[0])
axs[1].set_title('Physical Property')
axs[1].set_ylabel('Depth, y')
clbar.set_label('$\sigma = \exp(\mathbf{P}m)$')
plt.tight_layout()
plt.show()
if __name__ == '__main__':
run()
+47
View File
@@ -0,0 +1,47 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Mesh, Maps, Utils
def run(plotIt=True):
"""
Maps: Mesh2Mesh
===============
This mapping allows you to go from one mesh to another.
"""
M = Mesh.TensorMesh([100,100])
h1 = Utils.meshTensor([(6,7,-1.5),(6,10),(6,7,1.5)])
h1 = h1/h1.sum()
M2 = Mesh.TensorMesh([h1,h1])
V = Utils.ModelBuilder.randomModel(M.vnC, seed=79, its=50)
v = Utils.mkvc(V)
modh = Maps.Mesh2Mesh([M,M2])
modH = Maps.Mesh2Mesh([M2,M])
H = modH * v
h = modh * H
if not plotIt: return
import matplotlib.pyplot as plt
ax = plt.subplot(131)
M.plotImage(v, ax=ax)
ax.set_title('Fine Mesh (Original)')
ax = plt.subplot(132)
M2.plotImage(H,clim=[0,1],ax=ax)
ax.set_title('Course Mesh')
ax = plt.subplot(133)
M.plotImage(h,clim=[0,1],ax=ax)
ax.set_title('Fine Mesh (Interpolated)')
plt.show()
if __name__ == '__main__':
run()
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Mesh, Utils, np, SolverLU from SimPEG import Mesh, Utils, np, SolverLU
def run(plotIt=True): def run(plotIt=True):
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
def run(plotIt=True): def run(plotIt=True):
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
def run(plotIt=True): def run(plotIt=True):
@@ -1,3 +1,11 @@
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from builtins import int
from future import standard_library
standard_library.install_aliases()
from builtins import zip
from SimPEG import * from SimPEG import *
def run(plotIt=True, n=60): def run(plotIt=True, n=60):
@@ -87,7 +95,7 @@ def run(plotIt=True, n=60):
if elapsed > capture[jj]: if elapsed > capture[jj]:
PHIS += [(elapsed, phi.copy())] PHIS += [(elapsed, phi.copy())]
jj += 1 jj += 1
if ii % 10 == 0: print ii, elapsed if ii % 10 == 0: print(ii, elapsed)
ii += 1 ii += 1
if plotIt: if plotIt:
@@ -1,3 +1,10 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
def run(plotIt=True): def run(plotIt=True):
+11 -3
View File
@@ -1,3 +1,11 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import zip
from builtins import range
from SimPEG import * from SimPEG import *
def run(plotIt=True, n=60): def run(plotIt=True, n=60):
@@ -28,15 +36,15 @@ def run(plotIt=True, n=60):
axes[0].set_xlim([-1,17]) axes[0].set_xlim([-1,17])
axes[0].set_ylim([-1,17]) axes[0].set_ylim([-1,17])
for ii, loc in zip(range(M.nC),M.gridCC): for ii, loc in zip(list(range(M.nC)),M.gridCC):
axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='r') axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='r')
axes[0].plot(M.gridFx[:,0],M.gridFx[:,1], 'g>') axes[0].plot(M.gridFx[:,0],M.gridFx[:,1], 'g>')
for ii, loc in zip(range(M.nFx),M.gridFx): for ii, loc in zip(list(range(M.nFx)),M.gridFx):
axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='g') axes[0].text(loc[0]+0.2,loc[1],'%d'%ii, color='g')
axes[0].plot(M.gridFy[:,0],M.gridFy[:,1], 'm^') axes[0].plot(M.gridFy[:,0],M.gridFy[:,1], 'm^')
for ii, loc in zip(range(M.nFy),M.gridFy): for ii, loc in zip(list(range(M.nFy)),M.gridFy):
axes[0].text(loc[0]+0.2,loc[1]+0.2,'%d'%(ii+M.nFx), color='m') axes[0].text(loc[0]+0.2,loc[1]+0.2,'%d'%(ii+M.nFx), color='m')
axes[1].spy(M.faceDiv) axes[1].spy(M.faceDiv)
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
def run(plotIt=True): def run(plotIt=True):
+6
View File
@@ -1,3 +1,9 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
def run(plotIt=True): def run(plotIt=True):
+15 -7
View File
@@ -1,9 +1,19 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import * from SimPEG import *
from SimPEG.Utils import surface2ind_topo from SimPEG.Utils import surface2ind_topo
def run(plotIt=False, nx = 5, ny = 5): def run(plotIt=True, nx=5, ny=5):
""" """
Utils: surface2ind_topo
=======================
Here we show how to use :code:`Utils.surface2ind_topo` to identify cells below Here we show how to use :code:`Utils.surface2ind_topo` to identify cells below
a topographic surface. a topographic surface.
@@ -13,27 +23,25 @@ def run(plotIt=False, nx = 5, ny = 5):
xtopo = np.linspace(mesh.gridN[:,0].min(), mesh.gridN[:,0].max()) xtopo = np.linspace(mesh.gridN[:,0].min(), mesh.gridN[:,0].max())
topo = 0.4*np.sin(xtopo*5) # define a topographic surface topo = 0.4*np.sin(xtopo*5) # define a topographic surface
Topo = np.hstack([Utils.mkvc(xtopo,2),Utils.mkvc(topo,2)]) #make it an array Topo = np.hstack([Utils.mkvc(xtopo,2), Utils.mkvc(topo,2)]) #make it an array
indcc = surface2ind_topo(mesh, Topo,'CC') indcc = surface2ind_topo(mesh, Topo, 'CC')
if plotIt: if plotIt:
from matplotlib.pylab import plt from matplotlib.pylab import plt
from scipy.interpolate import interp1d from scipy.interpolate import interp1d
fig, ax = plt.subplots(1,1,figsize=(6,6)) fig, ax = plt.subplots(1,1, figsize=(6,6))
mesh.plotGrid(ax=ax, nodes=True, centers=True) mesh.plotGrid(ax=ax, nodes=True, centers=True)
ax.plot(xtopo,topo,'k',linewidth=1) ax.plot(xtopo,topo,'k',linewidth=1)
# ax.plot(mesh.vectorNx, interp1d(xtopo,topo)(mesh.vectorNx),'--k',linewidth=3)
ax.plot(mesh.vectorCCx, interp1d(xtopo,topo)(mesh.vectorCCx),'--k',linewidth=3) ax.plot(mesh.vectorCCx, interp1d(xtopo,topo)(mesh.vectorCCx),'--k',linewidth=3)
aveN2CC = Utils.sdiag(mesh.aveN2CC.T.sum(1))*mesh.aveN2CC.T aveN2CC = Utils.sdiag(mesh.aveN2CC.T.sum(1))*mesh.aveN2CC.T
a = aveN2CC * indcc a = aveN2CC * indcc
a[a > 0] = 1. a[a > 0] = 1.
a[a < 0.25] = np.nan a[a < 0.25] = np.nan
a = a.reshape(mesh.vnN, order='F') a = a.reshape(mesh.vnN, order='F')
masked_array = np.ma.array(a, mask=np.isnan(a)) masked_array = np.ma.array(a, mask=np.isnan(a))
ax.pcolor(mesh.vectorNx,mesh.vectorNy,masked_array.T, cmap = plt.cm.gray,alpha=0.2) ax.pcolor(mesh.vectorNx,mesh.vectorNy,masked_array.T, cmap=plt.cm.gray, alpha=0.2)
plt.show() plt.show()
+34 -26
View File
@@ -1,29 +1,37 @@
from __future__ import print_function
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import division
from builtins import open
from future import standard_library
standard_library.install_aliases()
# Run this file to add imports. # Run this file to add imports.
##### AUTOIMPORTS ##### ##### AUTOIMPORTS #####
import EM_FDEM_1D_Inversion from . import DC_Analytic_Dipole
import Mesh_QuadTree_Creation from . import DC_Forward_PseudoSection
import EM_TDEM_1D_Inversion from . import EM_FDEM_1D_Inversion
import Mesh_QuadTree_FaceDiv from . import EM_FDEM_Analytic_MagDipoleWholespace
import Mesh_Tensor_Creation from . import EM_Schenkel_Morrison_Casing
import FLOW_Richards_1D_Celia1990 from . import EM_TDEM_1D_Inversion
import DC_Forward_PseudoSection from . import FLOW_Richards_1D_Celia1990
import Mesh_Operators_CahnHilliard from . import Inversion_IRLS
import Mesh_Basic_Types from . import Inversion_Linear
import Inversion_IRLS from . import Maps_ComboMaps
import Inversion_Linear from . import Maps_Mesh2Mesh
import EM_Schenkel_Morrison_Casing from . import Mesh_Basic_ForwardDC
import MT_3D_Foward from . import Mesh_Basic_PlotImage
import Mesh_Basic_ForwardDC from . import Mesh_Basic_Types
import MT_1D_ForwardAndInversion from . import Mesh_Operators_CahnHilliard
import Utils_surface2ind_topo from . import Mesh_QuadTree_Creation
import MT_1D_analytic_nlayer_Earth from . import Mesh_QuadTree_FaceDiv
import EM_FDEM_Analytic_MagDipoleWholespace from . import Mesh_QuadTree_HangingNodes
import Mesh_Basic_PlotImage from . import Mesh_Tensor_Creation
import DC_Analytic_Dipole from . import MT_1D_ForwardAndInversion
import Mesh_QuadTree_HangingNodes from . import MT_3D_Foward
from . import Utils_surface2ind_topo
__examples__ = ["EM_FDEM_1D_Inversion", "Mesh_QuadTree_Creation", "EM_TDEM_1D_Inversion", "Mesh_QuadTree_FaceDiv", "Mesh_Tensor_Creation", "FLOW_Richards_1D_Celia1990", "DC_Forward_PseudoSection", "Mesh_Operators_CahnHilliard", "Mesh_Basic_Types", "Inversion_IRLS", "Inversion_Linear", "EM_Schenkel_Morrison_Casing", "MT_3D_Foward", "Mesh_Basic_ForwardDC", "MT_1D_ForwardAndInversion", "Utils_surface2ind_topo", "MT_1D_analytic_nlayer_Earth", "EM_FDEM_Analytic_MagDipoleWholespace", "Mesh_Basic_PlotImage", "DC_Analytic_Dipole", "Mesh_QuadTree_HangingNodes"] __examples__ = ["DC_Analytic_Dipole", "DC_Forward_PseudoSection", "EM_FDEM_1D_Inversion", "EM_FDEM_Analytic_MagDipoleWholespace", "EM_Schenkel_Morrison_Casing", "EM_TDEM_1D_Inversion", "FLOW_Richards_1D_Celia1990", "Inversion_IRLS", "Inversion_Linear", "Maps_ComboMaps", "Maps_Mesh2Mesh", "Mesh_Basic_ForwardDC", "Mesh_Basic_PlotImage", "Mesh_Basic_Types", "Mesh_Operators_CahnHilliard", "Mesh_QuadTree_Creation", "Mesh_QuadTree_FaceDiv", "Mesh_QuadTree_HangingNodes", "Mesh_Tensor_Creation", "MT_1D_ForwardAndInversion", "MT_3D_Foward", "Utils_surface2ind_topo"]
##### AUTOIMPORTS ##### ##### AUTOIMPORTS #####
@@ -39,7 +47,7 @@ if __name__ == '__main__':
# Create the examples dir in the docs folder. # Create the examples dir in the docs folder.
fName = os.path.realpath(__file__) fName = os.path.realpath(__file__)
docExamplesDir = os.path.sep.join(fName.split(os.path.sep)[:-3] + ['docs', 'examples']) docExamplesDir = os.path.sep.join(fName.split(os.path.sep)[:-3] + ['docs', 'content', 'examples'])
shutil.rmtree(docExamplesDir) shutil.rmtree(docExamplesDir)
os.makedirs(docExamplesDir) os.makedirs(docExamplesDir)
@@ -96,14 +104,14 @@ if __name__ == '__main__':
from SimPEG import Examples from SimPEG import Examples
Examples.%s.run() Examples.%s.run()
.. literalinclude:: ../../SimPEG/Examples/%s.py .. literalinclude:: ../../../SimPEG/Examples/%s.py
:language: python :language: python
:linenos: :linenos:
"""%(name,doc,name,name) """%(name,doc,name,name)
rst = os.path.sep.join((filePath.split(os.path.sep)[:-3] + ['docs', 'examples', name + '.rst'])) rst = os.path.sep.join((filePath.split(os.path.sep)[:-3] + ['docs', 'content', 'examples', name + '.rst']))
print 'Creating: %s.rst'%name print('Creating: %s.rst'%name)
f = open(rst, 'w') f = open(rst, 'w')
f.write(out) f.write(out)
f.close() f.close()
+14 -8
View File
@@ -1,14 +1,20 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import object
from SimPEG import Mesh, Maps, Utils, np from SimPEG import Mesh, Maps, Utils, np
from future.utils import with_metaclass
class NonLinearMap(object): class NonLinearMap(with_metaclass(Utils.SimPEGMetaClass, object)):
""" """
SimPEG NonLinearMap SimPEG NonLinearMap
""" """
__metaclass__ = Utils.SimPEGMetaClass
counter = None #: A SimPEG.Utils.Counter object counter = None #: A SimPEG.Utils.Counter object
mesh = None #: A SimPEG Mesh mesh = None #: A SimPEG Mesh
@@ -31,7 +37,7 @@ class NonLinearMap(object):
""" """
:param numpy.array u: fields :param numpy.array u: fields
:param numpy.array m: model :param numpy.array m: model
:rtype: scipy.csr_matrix :rtype: scipy.sparse.csr_matrix
:return: derivative of transformed model :return: derivative of transformed model
The *transform* changes the model into the physical property. The *transform* changes the model into the physical property.
@@ -44,7 +50,7 @@ class NonLinearMap(object):
""" """
:param numpy.array u: fields :param numpy.array u: fields
:param numpy.array m: model :param numpy.array m: model
:rtype: scipy.csr_matrix :rtype: scipy.sparse.csr_matrix
:return: derivative of transformed model :return: derivative of transformed model
The *transform* changes the model into the physical property. The *transform* changes the model into the physical property.
@@ -186,7 +192,7 @@ class _haverkamp_theta(NonLinearMap):
def transformDerivU(self, u, m): def transformDerivU(self, u, m):
self.setModel(m) self.setModel(m)
g = (self.alpha*((self.theta_s - self.theta_r)/ g = (self.alpha*((self.theta_s - self.theta_r) /
(self.alpha + abs(u)**self.beta)**2) (self.alpha + abs(u)**self.beta)**2)
*(-self.beta*abs(u)**(self.beta-1)*np.sign(u))) *(-self.beta*abs(u)**(self.beta-1)*np.sign(u)))
g[u >= 0] = 0 g[u >= 0] = 0
@@ -273,7 +279,7 @@ class _vangenuchten_theta(NonLinearMap):
def transform(self, u, m): def transform(self, u, m):
self.setModel(m) self.setModel(m)
m = 1 - 1.0/self.n m = 1 - 1.0/self.n
f = (( self.theta_s - self.theta_r )/ f = (( self.theta_s - self.theta_r ) /
((1+abs(self.alpha*u)**self.n)**m) + self.theta_r) ((1+abs(self.alpha*u)**self.n)**m) + self.theta_r)
if Utils.isScalar(self.theta_s): if Utils.isScalar(self.theta_s):
f[u >= 0] = self.theta_s f[u >= 0] = self.theta_s
@@ -343,7 +349,7 @@ class _vangenuchten_k(NonLinearMap):
Ks = self.Ks Ks = self.Ks
m = 1.0 - 1.0/n m = 1.0 - 1.0/n
g = I*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1.0)*np.sign(alpha*u)*(1.0/n - 1.0)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(I - 1)*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2*(abs(alpha*u)**n + 1)**(1.0/n - 2) - (2*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1)*np.sign(alpha*u)*(1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))/(((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1) + 1)*(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1.0/n)) g = I*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1.0)*np.sign(alpha*u)*(1.0/n - 1.0)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**(I - 1)*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)**2*(abs(alpha*u)**n + 1)**(1.0/n - 2) - (2*alpha*n*np.exp(Ks)*abs(alpha*u)**(n - 1)*np.sign(alpha*u)*(1.0/n - 1)*((abs(alpha*u)**n + 1)**(1.0/n - 1))**I*((1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1 - 1.0/n) - 1)*(abs(alpha*u)**n + 1)**(1.0/n - 2))/(((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1))+ 1)*(1 - 1.0/((abs(alpha*u)**n + 1)**(1.0/n - 1))**(1.0/(1.0/n - 1)))**(1.0/n)
g[u >= 0] = 0 g[u >= 0] = 0
g = Utils.sdiag(g) g = Utils.sdiag(g)
return g return g
+15 -8
View File
@@ -1,5 +1,12 @@
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import range
from SimPEG import * from SimPEG import *
from Empirical import RichardsMap from .Empirical import RichardsMap
import time import time
@@ -61,7 +68,7 @@ class RichardsSurvey(Survey.BaseSurvey):
@Utils.requires('prob') @Utils.requires('prob')
def eval(self, U, m): def eval(self, U, m):
Ds = range(len(self.rxList)) Ds = list(range(len(self.rxList)))
for ii, rx in enumerate(self.rxList): for ii, rx in enumerate(self.rxList):
Ds[ii] = rx.eval(U, m, Ds[ii] = rx.eval(U, m,
self.prob.mapping, self.prob.mapping,
@@ -73,7 +80,7 @@ class RichardsSurvey(Survey.BaseSurvey):
@Utils.requires('prob') @Utils.requires('prob')
def evalDeriv(self, U, m): def evalDeriv(self, U, m):
"""The Derivative with respect to the fields.""" """The Derivative with respect to the fields."""
Ds = range(len(self.rxList)) Ds = list(range(len(self.rxList)))
for ii, rx in enumerate(self.rxList): for ii, rx in enumerate(self.rxList):
Ds[ii] = rx.evalDeriv(U, m, Ds[ii] = rx.evalDeriv(U, m,
self.prob.mapping, self.prob.mapping,
@@ -135,12 +142,12 @@ class RichardsProblem(Problem.BaseTimeProblem):
@Utils.timeIt @Utils.timeIt
def fields(self, m): def fields(self, m):
tic = time.time() tic = time.time()
u = range(self.nT+1) u = list(range(self.nT+1))
u[0] = self.initialConditions u[0] = self.initialConditions
for ii, dt in enumerate(self.timeSteps): for ii, dt in enumerate(self.timeSteps):
bc = self.getBoundaryConditions(ii, u[ii]) bc = self.getBoundaryConditions(ii, u[ii])
u[ii+1] = self.rootFinder.root(lambda hn1m, return_g=True: self.getResidual(m, u[ii], hn1m, dt, bc, return_g=return_g), u[ii]) u[ii+1] = self.rootFinder.root(lambda hn1m, return_g=True: self.getResidual(m, u[ii], hn1m, dt, bc, return_g=return_g), u[ii])
if self.debug: print "Solving Fields (%4d/%d - %3.1f%% Done) %d Iterations, %4.2f seconds"%(ii+1, self.nT, 100.0*(ii+1)/self.nT, self.rootFinder.iter, time.time() - tic) if self.debug: print("Solving Fields (%4d/%d - %3.1f%% Done) %d Iterations, %4.2f seconds"%(ii+1, self.nT, 100.0*(ii+1)/self.nT, self.rootFinder.iter, time.time() - tic))
return u return u
@Utils.timeIt @Utils.timeIt
@@ -238,7 +245,7 @@ class RichardsProblem(Problem.BaseTimeProblem):
f = self.fields(m) f = self.fields(m)
nn = len(f)-1 nn = len(f)-1
Asubs, Adiags, Bs = range(nn), range(nn), range(nn) Asubs, Adiags, Bs = list(range(nn)), list(range(nn)), list(range(nn))
for ii in range(nn): for ii in range(nn):
dt = self.timeSteps[ii] dt = self.timeSteps[ii]
bc = self.getBoundaryConditions(ii, f[ii]) bc = self.getBoundaryConditions(ii, f[ii])
@@ -263,7 +270,7 @@ class RichardsProblem(Problem.BaseTimeProblem):
if f is None: if f is None:
f = self.fields(m) f = self.fields(m)
JvC = range(len(f)-1) # Cell to hold each row of the long vector. JvC = list(range(len(f)-1)) # Cell to hold each row of the long vector.
# This is done via forward substitution. # This is done via forward substitution.
bc = self.getBoundaryConditions(0, f[0]) bc = self.getBoundaryConditions(0, f[0])
@@ -295,7 +302,7 @@ class RichardsProblem(Problem.BaseTimeProblem):
bc = self.getBoundaryConditions(ii-1, f[ii-1]) bc = self.getBoundaryConditions(ii-1, f[ii-1])
Asub, Adiag, B = self.diagsJacobian(m, f[ii-1], f[ii], self.timeSteps[ii-1], bc) Asub, Adiag, B = self.diagsJacobian(m, f[ii-1], f[ii], self.timeSteps[ii-1], bc)
#select the correct part of v #select the correct part of v
vpart = range((ii)*Adiag.shape[0], (ii+1)*Adiag.shape[0]) vpart = list(range((ii)*Adiag.shape[0], (ii+1)*Adiag.shape[0]))
AdiaginvT = self.Solver(Adiag.T, **self.solverOpts) AdiaginvT = self.Solver(Adiag.T, **self.solverOpts)
JTvC = AdiaginvT * (PTv[vpart] - minus) JTvC = AdiaginvT * (PTv[vpart] - minus)
minus = Asub.T*JTvC # this is now the super diagonal. minus = Asub.T*JTvC # this is now the super diagonal.
+8 -2
View File
@@ -1,2 +1,8 @@
import Empirical from __future__ import absolute_import
from RichardsProblem import * from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from . import Empirical
from .RichardsProblem import *
+7 -1
View File
@@ -1 +1,7 @@
import Richards from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from . import Richards
+11 -2
View File
@@ -1,4 +1,13 @@
import Utils, numpy as np, scipy.sparse as sp from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import range
from builtins import object
from . import Utils
import numpy as np, scipy.sparse as sp
class Fields(object): class Fields(object):
"""Fancy Field Storage """Fancy Field Storage
@@ -244,7 +253,7 @@ class TimeFields(Fields):
out = func(pointerFields, srcII, timeII) out = func(pointerFields, srcII, timeII)
else: #loop over the time steps else: #loop over the time steps
nT = pointerShape[2] nT = pointerShape[2]
out = range(nT) out = list(range(nT))
for i, TIND_i in enumerate(timeII): for i, TIND_i in enumerate(timeII):
fieldI = pointerFields[:,:,i] fieldI = pointerFields[:,:,i]
if fieldI.shape[0] == fieldI.size: if fieldI.shape[0] == fieldI.size:
+19 -12
View File
@@ -1,14 +1,21 @@
import Utils, Survey, Problem, numpy as np, scipy.sparse as sp, gc from __future__ import print_function
from Utils.SolverUtils import * from __future__ import absolute_import
import DataMisfit from __future__ import unicode_literals
import Regularization from __future__ import division
from future import standard_library
standard_library.install_aliases()
from builtins import object
from . import Utils, Survey, Problem
import numpy as np, scipy.sparse as sp, gc
from .Utils.SolverUtils import *
from . import DataMisfit
from . import Regularization
from future.utils import with_metaclass
class BaseInvProblem(object): class BaseInvProblem(with_metaclass(Utils.SimPEGMetaClass, object)):
"""BaseInvProblem(dmisfit, reg, opt)""" """BaseInvProblem(dmisfit, reg, opt)"""
__metaclass__ = Utils.SimPEGMetaClass
beta = 1.0 #: Trade-off parameter beta = 1.0 #: Trade-off parameter
debug = False #: Print debugging information debug = False #: Print debugging information
@@ -54,10 +61,10 @@ class BaseInvProblem(object):
Called when inversion is first starting. Called when inversion is first starting.
""" """
if self.debug: print 'Calling InvProblem.startup' if self.debug: print('Calling InvProblem.startup')
if self.reg.mref is None: if self.reg.mref is None:
print 'SimPEG.InvProblem will set Regularization.mref to m0.' print('SimPEG.InvProblem will set Regularization.mref to m0.')
self.reg.mref = m0 self.reg.mref = m0
self.phi_d = np.nan self.phi_d = np.nan
@@ -65,8 +72,8 @@ class BaseInvProblem(object):
self.curModel = m0 self.curModel = m0
print """SimPEG.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv. print("""SimPEG.InvProblem is setting bfgsH0 to the inverse of the eval2Deriv.
***Done using same Solver and solverOpts as the problem***""" ***Done using same Solver and solverOpts as the problem***""")
self.opt.bfgsH0 = self.prob.Solver(self.reg.eval2Deriv(self.curModel), **self.prob.solverOpts) self.opt.bfgsH0 = self.prob.Solver(self.reg.eval2Deriv(self.curModel), **self.prob.solverOpts)
@property @property
@@ -87,7 +94,7 @@ class BaseInvProblem(object):
for mtest, u_ofmtest in self.warmstart: for mtest, u_ofmtest in self.warmstart:
if m is mtest: if m is mtest:
f = u_ofmtest f = u_ofmtest
if self.debug: print 'InvProb is Warm Starting!' if self.debug: print('InvProb is Warm Starting!')
break break
if f is None: if f is None:
+11 -5
View File
@@ -1,18 +1,24 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from builtins import object
import SimPEG import SimPEG
from SimPEG import Utils, sp, np from SimPEG import Utils, sp, np
from Optimization import Remember, IterationPrinters, StoppingCriteria from .Optimization import Remember, IterationPrinters, StoppingCriteria
import Directives from . import Directives
from future.utils import with_metaclass
class BaseInversion(object): class BaseInversion(with_metaclass(Utils.SimPEGMetaClass, object)):
""" """
Inversion Class. Inversion Class.
""" """
__metaclass__ = Utils.SimPEGMetaClass
name = 'BaseInversion' name = 'BaseInversion'
debug = False #: Print debugging information debug = False #: Print debugging information
+138
View File
@@ -0,0 +1,138 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from SimPEG import SolverLU as SimpegSolver, PropMaps, Utils, mkvc, sp, np
from SimPEG.EM.FDEM.ProblemFDEM import BaseFDEMProblem
from .SurveyMT import Survey, Data
from .FieldsMT import BaseMTFields
class BaseMTProblem(BaseFDEMProblem):
"""
Base class for all Natural source problems.
"""
def __init__(self, mesh, **kwargs):
BaseFDEMProblem.__init__(self, mesh, **kwargs)
Utils.setKwargs(self, **kwargs)
# Set the default pairs of the problem
surveyPair = Survey
dataPair = Data
fieldsPair = BaseMTFields
# Set the solver
Solver = SimpegSolver
solverOpts = {}
verbose = False
# Notes:
# Use the forward and devs from BaseFDEMProblem
# Might need to add more stuff here.
## NEED to clean up the Jvec and Jtvec to use Zero and Identities for None components.
def Jvec(self, m, v, f=None):
"""
Function to calculate the data sensitivities dD/dm times a vector.
:param numpy.ndarray m (nC, 1) - conductive model
:param numpy.ndarray v (nC, 1) - random vector
:param MTfields object (optional) - MT fields object, if not given it is calculated
:rtype: MTdata object
:return: Data sensitivities wrt m
"""
# Calculate the fields
if f is None:
f= self.fields(m)
# Set current model
self.curModel = m
# Initiate the Jv object
Jv = self.dataPair(self.survey)
# Loop all the frequenies
for freq in self.survey.freqs:
dA_du = self.getA(freq) #
dA_duI = self.Solver(dA_du, **self.solverOpts)
for src in self.survey.getSrcByFreq(freq):
# We need fDeriv_m = df/du*du/dm + df/dm
# Construct du/dm, it requires a solve
# NOTE: need to account for the 2 polarizations in the derivatives.
f_src = f[src,:]
# dA_dm and dRHS_dm should be of size nE,2, so that we can multiply by dA_duI. The 2 columns are each of the polarizations.
dA_dm = self.getADeriv_m(freq, f_src, v) # Size: nE,2 (u_px,u_py) in the columns.
dRHS_dm = self.getRHSDeriv_m(freq, v) # Size: nE,2 (u_px,u_py) in the columns.
if dRHS_dm is None:
du_dm = dA_duI * ( -dA_dm )
else:
du_dm = dA_duI * ( -dA_dm + dRHS_dm )
# Calculate the projection derivatives
for rx in src.rxList:
# Get the projection derivative
# v should be of size 2*nE (for 2 polarizations)
PDeriv_u = lambda t: rx.evalDeriv(src, self.mesh, f, t) # wrt u, we don't have have PDeriv wrt m
Jv[src, rx] = PDeriv_u(mkvc(du_dm))
dA_duI.clean()
# Return the vectorized sensitivities
return mkvc(Jv)
def Jtvec(self, m, v, f=None):
"""
Function to calculate the transpose of the data sensitivities (dD/dm)^T times a vector.
:param numpy.ndarray m (nC, 1) - conductive model
:param numpy.ndarray v (nD, 1) - vector
:param MTfields object u (optional) - MT fields object, if not given it is calculated
:rtype: MTdata object
:return: Data sensitivities wrt m
"""
if f is None:
f = self.fields(m)
self.curModel = m
# Ensure v is a data object.
if not isinstance(v, self.dataPair):
v = self.dataPair(self.survey, v)
Jtv = np.zeros(m.size)
for freq in self.survey.freqs:
AT = self.getA(freq).T
ATinv = self.Solver(AT, **self.solverOpts)
for src in self.survey.getSrcByFreq(freq):
ftype = self._fieldType + 'Solution'
f_src = f[src, :]
for rx in src.rxList:
# Get the adjoint evalDeriv
# PTv needs to be nE,
PTv = rx.evalDeriv(src, self.mesh, f, mkvc(v[src, rx],2), adjoint=True) # wrt u, need possibility wrt m
# Get the
dA_duIT = ATinv * PTv
dA_dmT = self.getADeriv_m(freq, f_src, mkvc(dA_duIT), adjoint=True)
dRHS_dmT = self.getRHSDeriv_m(freq, mkvc(dA_duIT), adjoint=True)
# Make du_dmT
if dRHS_dmT is None:
du_dmT = -dA_dmT
else:
du_dmT = -dA_dmT + dRHS_dmT
# Select the correct component
# du_dmT needs to be of size nC,
real_or_imag = rx.projComp
if real_or_imag == 'real':
Jtv += du_dmT.real
elif real_or_imag == 'imag':
Jtv += -du_dmT.real
else:
raise Exception('Must be real or imag')
# Clean the factorization, clear memory.
ATinv.clean()
return Jtv
@@ -1,24 +1,27 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Survey, Utils, Problem, np, sp, mkvc from SimPEG import Survey, Utils, Problem, np, sp, mkvc
from scipy.constants import mu_0 from scipy.constants import mu_0
import sys import sys
from numpy.lib import recfunctions as recFunc from numpy.lib import recfunctions as recFunc
from SimPEG.EM.Utils import omega from SimPEG.EM.Utils import omega
############## ##############
### Fields ### ### Fields ###
############## ##############
class BaseNSEMFields(Problem.Fields): class BaseMTFields(Problem.Fields):
"""Field Storage for a NSEM survey.""" """Field Storage for a MT survey."""
knownFields = {} knownFields = {}
dtype = complex dtype = complex
###########
# 1D Fields class Fields1D_e(BaseMTFields):
###########
class Fields1D_ePrimSec(BaseNSEMFields):
""" """
Fields storage for the 1D NSEM solution. Fields storage for the 1D MT solution.
""" """
knownFields = {'e_1dSolution':'F'} knownFields = {'e_1dSolution':'F'}
aliasFields = { aliasFields = {
@@ -31,119 +34,7 @@ class Fields1D_ePrimSec(BaseNSEMFields):
} }
def __init__(self,mesh,survey,**kwargs): def __init__(self,mesh,survey,**kwargs):
BaseNSEMFields.__init__(self,mesh,survey,**kwargs) BaseMTFields.__init__(self,mesh,survey,**kwargs)
def _ePrimary(self, eSolution, srcList):
ePrimary = np.zeros_like(eSolution)
for i, src in enumerate(srcList):
ep = src.ePrimary(self.survey.prob)
if ep is not None:
ePrimary[:,i] = ep[:,-1]
return ePrimary
def _eSecondary(self, eSolution, srcList):
return eSolution
def _e(self, eSolution, srcList):
return self._ePrimary(eSolution,srcList) + self._eSecondary(eSolution,srcList)
def _eDeriv_u(self, src, du_dm_v, adjoint = False):
return Utils.Identity()*du_dm_v
def _eDeriv_m(self, src, v, adjoint = False):
# assuming primary does not depend on the model
return Utils.Zero()
def _bPrimary(self, eSolution, srcList):
bPrimary = np.zeros([self.survey.mesh.nE,eSolution.shape[1]], dtype = complex)
for i, src in enumerate(srcList):
bp = src.bPrimary(self.survey.prob)
if bp is not None:
bPrimary[:,i] += bp[:,-1]
return bPrimary
def _bSecondary(self, eSolution, srcList):
C = self.mesh.nodalGrad
b = (C * eSolution)
for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq))
# There is no magnetic source in the MT problem
# S_m, _ = src.eval(self.survey.prob)
# if S_m is not None:
# b[:,i] += 1./(1j*omega(src.freq)) * S_m
return b
def _b(self, eSolution, srcList):
return self._bPrimary(eSolution, srcList) + self._bSecondary(eSolution, srcList)
def _bSecondaryDeriv_u(self, src, v, adjoint = False):
C = self.mesh.nodalGrad
if adjoint:
return - 1./(1j*omega(src.freq)) * (C.T * v)
return - 1./(1j*omega(src.freq)) * (C * v)
def _bSecondaryDeriv_m(self, src, v, adjoint = False):
# Doesn't depend on m
# _, S_eDeriv = src.evalDeriv(self.survey.prob, adjoint)
# S_eDeriv = S_eDeriv(v)
# if S_eDeriv is not None:
# return 1./(1j * omega(src.freq)) * S_eDeriv
return None
def _bDeriv_u(self, src, v, adjoint=False):
# Primary does not depend on u
return self._bSecondaryDeriv_u(src, v, adjoint)
def _bDeriv_m(self, src, v, adjoint=False):
# Assuming the primary does not depend on the model
return self._bSecondaryDeriv_m(src, v, adjoint)
def _fDeriv_u(self, src, v, adjoint=False):
"""
Derivative of the fields object wrt u.
:param NSEMsrc src: NSEM source
:param numpy.ndarray v: random vector of f_sol.size
This function stacks the fields derivatives appropriately
return a vector of size (nreEle+nrbEle)
"""
de_du = v #Utils.spdiag(np.ones((self.nF,)))
db_du = self._bDeriv_u(src, v, adjoint)
# Return the stack
# This doesn't work...
return np.vstack((de_du,db_du))
def _fDeriv_m(self, src, v, adjoint=False):
"""
Derivative of the fields object wrt m.
This function stacks the fields derivatives appropriately
"""
return None
class Fields1D_eTotal(BaseNSEMFields):
"""
Fields storage for the 1D NSEM solution solved with for a total domain formulation.
Used in conjuction with Problem1D_eTotal.
"""
knownFields = {'e_1dSolution':'F'}
aliasFields = {
'e_1d' : ['e_1dSolution','F','_e'],
'e_1dPrimary' : ['e_1dSolution','F','_ePrimary'],
'e_1dSecondary' : ['e_1dSolution','F','_eSecondary'],
'b_1d' : ['e_1dSolution','E','_b'],
'b_1dPrimary' : ['e_1dSolution','E','_bPrimary'],
'b_1dSecondary' : ['e_1dSolution','E','_bSecondary']
}
def __init__(self,mesh,survey,**kwargs):
BaseNSEMFields.__init__(self,mesh,survey,**kwargs)
def _ePrimary(self, eSolution, srcList): def _ePrimary(self, eSolution, srcList):
ePrimary = np.zeros_like(eSolution) ePrimary = np.zeros_like(eSolution)
@@ -178,7 +69,7 @@ class Fields1D_eTotal(BaseNSEMFields):
C = self.mesh.nodalGrad C = self.mesh.nodalGrad
b = (C * eSolution) b = (C * eSolution)
for i, src in enumerate(srcList): for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq)) b[:,i] *= -1./(1j*omega(src.freq))
# There is no magnetic source in the MT problem # There is no magnetic source in the MT problem
# S_m, _ = src.eval(self.survey.prob) # S_m, _ = src.eval(self.survey.prob)
# if S_m is not None: # if S_m is not None:
@@ -214,7 +105,7 @@ class Fields1D_eTotal(BaseNSEMFields):
""" """
Derivative of the fields object wrt u. Derivative of the fields object wrt u.
:param NSEMsrc src: NSEM source :param MTsrc src: MT source
:param numpy.ndarray v: random vector of f_sol.size :param numpy.ndarray v: random vector of f_sol.size
This function stacks the fields derivatives appropriately This function stacks the fields derivatives appropriately
@@ -235,18 +126,9 @@ class Fields1D_eTotal(BaseNSEMFields):
""" """
return None return None
class Fields3D_e(BaseMTFields):
###########
# 2D Fields
###########
###########
# 3D Fields
###########
class Fields3D_ePrimSec(BaseNSEMFields):
""" """
Fields storage for the 3D NSEM solution. Labels polarizations by px and py. Fields storage for the 3D MT solution. Labels polarizations by px and py.
:param SimPEG object mesh: The solution mesh :param SimPEG object mesh: The solution mesh
:param SimPEG object survey: A survey object :param SimPEG object survey: A survey object
@@ -271,7 +153,7 @@ class Fields3D_ePrimSec(BaseNSEMFields):
} }
def __init__(self,mesh,survey,**kwargs): def __init__(self,mesh,survey,**kwargs):
BaseNSEMFields.__init__(self,mesh,survey,**kwargs) BaseMTFields.__init__(self,mesh,survey,**kwargs)
def _e_pxPrimary(self, e_pxSolution, srcList): def _e_pxPrimary(self, e_pxSolution, srcList):
e_pxPrimary = np.zeros_like(e_pxSolution) e_pxPrimary = np.zeros_like(e_pxSolution)
@@ -312,7 +194,7 @@ class Fields3D_ePrimSec(BaseNSEMFields):
# adjoint: returns a 2*nE long vector with zero's for py # adjoint: returns a 2*nE long vector with zero's for py
return np.vstack((v,np.zeros_like(v))) return np.vstack((v,np.zeros_like(v)))
# Not adjoint: return only the px part of the vector # Not adjoint: return only the px part of the vector
return v[:len(v)/2] return v[:len(v)//2]
def _e_pyDeriv_u(self, src, v, adjoint = False): def _e_pyDeriv_u(self, src, v, adjoint = False):
''' '''
@@ -322,7 +204,7 @@ class Fields3D_ePrimSec(BaseNSEMFields):
# adjoint: returns a 2*nE long vector with zero's for px # adjoint: returns a 2*nE long vector with zero's for px
return np.vstack((np.zeros_like(v),v)) return np.vstack((np.zeros_like(v),v))
# Not adjoint: return only the px part of the vector # Not adjoint: return only the px part of the vector
return v[len(v)/2::] return v[len(v)//2::]
def _e_pxDeriv_m(self, src, v, adjoint = False): def _e_pxDeriv_m(self, src, v, adjoint = False):
# assuming primary does not depend on the model # assuming primary does not depend on the model
@@ -351,8 +233,8 @@ class Fields3D_ePrimSec(BaseNSEMFields):
C = self.mesh.edgeCurl C = self.mesh.edgeCurl
b = (C * e_pxSolution) b = (C * e_pxSolution)
for i, src in enumerate(srcList): for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq)) b[:,i] *= -1./(1j*omega(src.freq))
# There is no magnetic source in the NSEM problem # There is no magnetic source in the MT problem
# S_m, _ = src.eval(self.survey.prob) # S_m, _ = src.eval(self.survey.prob)
# if S_m is not None: # if S_m is not None:
# b[:,i] += 1./(1j*omega(src.freq)) * S_m # b[:,i] += 1./(1j*omega(src.freq)) * S_m
@@ -362,8 +244,8 @@ class Fields3D_ePrimSec(BaseNSEMFields):
C = self.mesh.edgeCurl C = self.mesh.edgeCurl
b = (C * e_pySolution) b = (C * e_pySolution)
for i, src in enumerate(srcList): for i, src in enumerate(srcList):
b[:,i] *= - 1./(1j*omega(src.freq)) b[:,i] *= -1./(1j*omega(src.freq))
# There is no magnetic source in the NSEM problem # There is no magnetic source in the MT problem
# S_m, _ = src.eval(self.survey.prob) # S_m, _ = src.eval(self.survey.prob)
# if S_m is not None: # if S_m is not None:
# b[:,i] += 1./(1j*omega(src.freq)) * S_m # b[:,i] += 1./(1j*omega(src.freq)) * S_m
@@ -426,7 +308,7 @@ class Fields3D_ePrimSec(BaseNSEMFields):
""" """
Derivative of the fields object wrt u. Derivative of the fields object wrt u.
:param NSEMsrc src: NSEM source :param MTsrc src: MT source
:param numpy.ndarray v: random vector of f_sol.size :param numpy.ndarray v: random vector of f_sol.size
This function stacks the fields derivatives appropriately This function stacks the fields derivatives appropriately
@@ -443,7 +325,7 @@ class Fields3D_ePrimSec(BaseNSEMFields):
""" """
Derivative of the fields object wrt u. Derivative of the fields object wrt u.
:param NSEMsrc src: NSEM source :param MTsrc src: MT source
:param numpy.ndarray v: random vector of f_sol.size :param numpy.ndarray v: random vector of f_sol.size
This function stacks the fields derivatives appropriately This function stacks the fields derivatives appropriately
@@ -472,4 +354,4 @@ class Fields3D_ePrimSec(BaseNSEMFields):
This function stacks the fields derivatives appropriately This function stacks the fields derivatives appropriately
""" """
# The fields have no dependance to the model. # The fields have no dependance to the model.
return None return None
+297
View File
@@ -0,0 +1,297 @@
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG.EM.Utils import omega
from SimPEG import mkvc
from scipy.constants import mu_0
from SimPEG.MT.BaseMT import BaseMTProblem
from SimPEG.MT.SurveyMT import Survey, Data
from SimPEG.MT.FieldsMT import Fields1D_e
from SimPEG.MT.Utils.MT1Danalytic import getEHfields
import numpy as np
import multiprocessing, sys, time
class eForm_psField(BaseMTProblem):
"""
A MT problem soving a e formulation and primary/secondary fields decomposion.
By eliminating the magnetic flux density using
.. math ::
\mathbf{b} = \\frac{1}{i \omega}\\left(-\mathbf{C} \mathbf{e} \\right)
we can write Maxwell's equations as a second order system in \\\(\\\mathbf{e}\\\) only:
.. math ::
\\left(\mathbf{C}^T \mathbf{M^e_{\mu^{-1}}} \mathbf{C} + i \omega \mathbf{M^f_\sigma}] \mathbf{e}_{s} =& i \omega \mathbf{M^f_{\delta \sigma}} \mathbf{e}_{p}
which we solve for \\\(\\\mathbf{e_s}\\\). The total field \\\mathbf{e}\\ = \\\mathbf{e_p}\\ + \\\mathbf{e_s}\\.
The primary field is estimated from a background model (commonly half space ).
"""
# From FDEMproblem: Used to project the fields. Currently not used for MTproblem.
_fieldType = 'e_1d'
_eqLocs = 'EF'
_sigmaPrimary = None
def __init__(self, mesh, **kwargs):
BaseMTProblem.__init__(self, mesh, **kwargs)
self.fieldsPair = Fields1D_e
# self._sigmaPrimary = sigmaPrimary
@property
def MeMui(self):
"""
Edge inner product matrix
"""
if getattr(self, '_MeMui', None) is None:
self._MeMui = self.mesh.getEdgeInnerProduct(old_div(1.0,mu_0))
return self._MeMui
@property
def MfSigma(self):
"""
Edge inner product matrix
"""
if getattr(self, '_MfSigma', None) is None:
self._MfSigma = self.mesh.getFaceInnerProduct(self.curModel.sigma)
return self._MfSigma
@property
def sigmaPrimary(self):
"""
A background model, use for the calculation of the primary fields.
"""
return self._sigmaPrimary
@sigmaPrimary.setter
def sigmaPrimary(self, val):
# Note: TODO add logic for val, make sure it is the correct size.
self._sigmaPrimary = val
def getA(self, freq):
"""
Function to get the A matrix.
:param float freq: Frequency
:rtype: scipy.sparse.csr_matrix
:return: A
"""
# Note: need to use the code above since in the 1D problem I want
# e to live on Faces(nodes) and h on edges(cells). Might need to rethink this
# Possible that _fieldType and _eqLocs can fix this
MeMui = self.MeMui
MfSigma = self.MfSigma
C = self.mesh.nodalGrad
# Make A
A = C.T*MeMui*C + 1j*omega(freq)*MfSigma
# Either return full or only the inner part of A
return A
def getADeriv_m(self, freq, u, v, adjoint=False):
"""
The derivative of A wrt sigma
"""
dsig_dm = self.curModel.sigmaDeriv
MeMui = self.MeMui
#
u_src = u['e_1dSolution']
dMfSigma_dm = self.mesh.getFaceInnerProductDeriv(self.curModel.sigma)(u_src) * self.curModel.sigmaDeriv
if adjoint:
return 1j * omega(freq) * ( dMfSigma_dm.T * v )
# Note: output has to be nN/nF, not nC/nE.
# v should be nC
return 1j * omega(freq) * ( dMfSigma_dm * v )
def getRHS(self, freq):
"""
Function to return the right hand side for the system.
:param float freq: Frequency
:rtype: numpy.ndarray (nF, 1), numpy.ndarray (nF, 1)
:return: RHS for 1 polarizations, primary fields
"""
# Get sources for the frequncy(polarizations)
Src = self.survey.getSrcByFreq(freq)[0]
S_e = Src.S_e(self)
return -1j * omega(freq) * S_e
def getRHSDeriv_m(self, freq, v, adjoint=False):
"""
The derivative of the RHS wrt sigma
"""
Src = self.survey.getSrcByFreq(freq)[0]
S_eDeriv = Src.S_eDeriv_m(self, v, adjoint)
return -1j * omega(freq) * S_eDeriv
def fields(self, m):
'''
Function to calculate all the fields for the model m.
:param np.ndarray (nC,) m: Conductivity model
'''
# Set the current model
self.curModel = m
F = Fields1D_e(self.mesh, self.survey)
for freq in self.survey.freqs:
if self.verbose:
startTime = time.time()
print('Starting work for {:.3e}'.format(freq))
sys.stdout.flush()
A = self.getA(freq)
rhs = self.getRHS(freq)
Ainv = self.Solver(A, **self.solverOpts)
e_s = Ainv * rhs
# Store the fields
Src = self.survey.getSrcByFreq(freq)[0]
# NOTE: only store the e_solution(secondary), all other components calculated in the fields object
F[Src, 'e_1dSolution'] = e_s[:,-1] # Only storing the yx polarization as 1d
# Note curl e = -iwb so b = -curl e /iw
# b = -( self.mesh.nodalGrad * e )/( 1j*omega(freq) )
# F[Src, 'b_1d'] = b[:,1]
if self.verbose:
print('Ran for {:f} seconds'.format(time.time()-startTime))
sys.stdout.flush()
return F
# Note this is not fully functional.
# Missing:
# Fields class corresponding to the fields
# Update Jvec and Jtvec to include all the derivatives components
# Other things ...
class eForm_TotalField(BaseMTProblem):
"""
A MT problem solving a e formulation and a Total bondary domain decompostion.
Solves the equation:
Math:
"""
# From FDEMproblem: Used to project the fields. Currently not used for MTproblem.
_fieldType = 'e'
_eqLocs = 'EF'
def __init__(self, mesh, **kwargs):
BaseMTProblem.__init__(self, mesh, **kwargs)
@property
def MeMui(self):
"""
Edge inner product matrix
"""
if getattr(self, '_MeMui', None) is None:
self._MeMui = self.mesh.getEdgeInnerProduct(old_div(1.0,mu_0))
return self._MeMui
@property
def MfSigma(self):
"""
Edge inner product matrix
"""
if getattr(self, '_MfSigma', None) is None:
self._MfSigma = self.mesh.getFaceInnerProduct(self.curModel.sigma)
return self._MfSigma
def getA(self, freq, full=False):
"""
Function to get the A matrix.
:param float freq: Frequency
:param logic full: Return full A or the inner part
:rtype: scipy.sparse.csr_matrix
:return: A
"""
MeMui = self.MeMui
MfSigma = self.MfSigma
# Note: need to use the code above since in the 1D problem I want
# e to live on Faces(nodes) and h on edges(cells). Might need to rethink this
# Possible that _fieldType and _eqLocs can fix this
# MeMui = self.MfMui
# MfSigma = self.MfSigma
C = self.mesh.nodalGrad
# Make A
A = C.T*MeMui*C + 1j*omega(freq)*MfSigma
# Either return full or only the inner part of A
if full:
return A
else:
return A[1:-1,1:-1]
def getADeriv_m(self, freq, u, v, adjoint=False):
raise NotImplementedError('getADeriv is not implemented')
def getRHS(self, freq):
"""
Function to return the right hand side for the system.
:param float freq: Frequency
:rtype: numpy.ndarray (nE, 2), numpy.ndarray (nE, 2)
:return: RHS for both polarizations, primary fields
"""
# Get sources for the frequency
# NOTE: Need to use the source information, doesn't really apply in 1D
src = self.survey.getSrcByFreq(freq)
# Get the full A
A = self.getA(freq,full=True)
# Define the outer part of the solution matrix
Aio = A[1:-1,[0,-1]]
Ed, Eu, Hd, Hu = getEHfields(self.mesh,self.curModel.sigma,freq,self.mesh.vectorNx)
Etot = (Ed + Eu)
sourceAmp = 1.0
Etot = ((old_div(Etot,Etot[-1]))*sourceAmp) # Scale the fields to be equal to sourceAmp at the top
## Note: The analytic solution is derived with e^iwt
eBC = np.r_[Etot[0],Etot[-1]]
# The right hand side
return -Aio*eBC, eBC
def getRHSderiv_m(self, freq, backSigma, u, v, adjoint=False):
raise NotImplementedError('getRHSDeriv not implemented yet')
return None
def fields(self, m):
'''
Function to calculate all the fields for the model m.
:param np.ndarray (nC,) m: Conductivity model
:param np.ndarray (nC,) m_back: Background conductivity model
'''
self.curModel = m
# RHS, CalcFields = self.getRHS(freq,m_back), self.calcFields
F = Fields1D_e(self.mesh, self.survey)
for freq in self.survey.freqs:
if self.verbose:
startTime = time.time()
print('Starting work for {:.3e}'.format(freq))
sys.stdout.flush()
A = self.getA(freq)
rhs, e_o = self.getRHS(freq)
Ainv = self.Solver(A, **self.solverOpts)
e_i = Ainv * rhs
e = mkvc(np.r_[e_o[0], e_i, e_o[1]],2)
# Store the fields
Src = self.survey.getSrcByFreq(freq)
# NOTE: only store e fields
F[Src, 'e_1dSolution'] = e[:,0]
if self.verbose:
print('Ran for {:f} seconds'.format(time.time()-startTime))
sys.stdout.flush()
return F
+7
View File
@@ -0,0 +1,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .Probs import eForm_TotalField, eForm_psField
View File
+7
View File
@@ -0,0 +1,7 @@
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
pass
+144
View File
@@ -0,0 +1,144 @@
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import division
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from SimPEG import Survey, Problem, Utils, Models, np, sp, mkvc, SolverLU as SimpegSolver
from SimPEG.EM.Utils import omega
from scipy.constants import mu_0
from SimPEG.MT.BaseMT import BaseMTProblem
from SimPEG.MT.SurveyMT import Survey, Data
from SimPEG.MT.FieldsMT import Fields3D_e
import multiprocessing, sys, time
class eForm_ps(BaseMTProblem):
"""
A MT problem solving a e formulation and a primary/secondary fields decompostion.
By eliminating the magnetic flux density using
.. math ::
\mathbf{b} = \\frac{1}{i \omega}\\left(-\mathbf{C} \mathbf{e} \\right)
we can write Maxwell's equations as a second order system in \\\(\\\mathbf{e}\\\) only:
.. math ::
\\left(\mathbf{C}^T \mathbf{M^f_{\mu^{-1}}} \mathbf{C} + i \omega \mathbf{M^e_\sigma}] \mathbf{e}_{s} =& i \omega \mathbf{M^e_{\delta \sigma}} \mathbf{e}_{p}
which we solve for \\\(\\\mathbf{e_s}\\\). The total field \\\mathbf{e}\\ = \\\mathbf{e_p}\\ + \\\mathbf{e_s}\\.
The primary field is estimated from a background model (commonly as a 1D model).
"""
# From FDEMproblem: Used to project the fields. Currently not used for MTproblem.
_fieldType = 'e'
_eqLocs = 'FE'
fieldsPair = Fields3D_e
_sigmaPrimary = None
def __init__(self, mesh, **kwargs):
BaseMTProblem.__init__(self, mesh, **kwargs)
@property
def sigmaPrimary(self):
"""
A background model, use for the calculation of the primary fields.
"""
return self._sigmaPrimary
@sigmaPrimary.setter
def sigmaPrimary(self, val):
# Note: TODO add logic for val, make sure it is the correct size.
self._sigmaPrimary = val
def getA(self, freq):
"""
Function to get the A system.
:param float freq: Frequency
:rtype: scipy.sparse.csr_matrix
:return: A
"""
Mmui = self.MfMui
Msig = self.MeSigma
C = self.mesh.edgeCurl
return C.T*Mmui*C + 1j*omega(freq)*Msig
def getADeriv_m(self, freq, u, v, adjoint=False):
"""
Calculate the derivative of A wrt m.
"""
# This considers both polarizations and returns a nE,2 matrix for each polarization
if adjoint:
dMe_dsigV = sp.hstack(( self.MeSigmaDeriv( u['e_pxSolution'] ).T, self.MeSigmaDeriv(u['e_pySolution'] ).T ))*v
else:
# Need a nE,2 matrix to be returned
dMe_dsigV = np.hstack(( mkvc(self.MeSigmaDeriv( u['e_pxSolution'] )*v,2), mkvc( self.MeSigmaDeriv(u['e_pySolution'] )*v,2) ))
return 1j * omega(freq) * dMe_dsigV
def getRHS(self, freq):
"""
Function to return the right hand side for the system.
:param float freq: Frequency
:rtype: numpy.ndarray (nE, 2), numpy.ndarray (nE, 2)
:return: RHS for both polarizations, primary fields
"""
# Get sources for the frequncy(polarizations)
Src = self.survey.getSrcByFreq(freq)[0]
S_e = Src.S_e(self)
return -1j * omega(freq) * S_e
def getRHSDeriv_m(self, freq, v, adjoint=False):
"""
The derivative of the RHS with respect to sigma
"""
Src = self.survey.getSrcByFreq(freq)[0]
S_eDeriv = Src.S_eDeriv_m(self, v, adjoint)
return -1j * omega(freq) * S_eDeriv
def fields(self, m):
'''
Function to calculate all the fields for the model m.
:param np.ndarray (nC,) m: Conductivity model
'''
# Set the current model
self.curModel = m
F = Fields3D_e(self.mesh, self.survey)
for freq in self.survey.freqs:
if self.verbose:
startTime = time.time()
print('Starting work for {:.3e}'.format(freq))
sys.stdout.flush()
A = self.getA(freq)
rhs = self.getRHS(freq)
# Solve the system
Ainv = self.Solver(A, **self.solverOpts)
e_s = Ainv * rhs
# Store the fields
Src = self.survey.getSrcByFreq(freq)[0]
# Store the fieldss
F[Src, 'e_pxSolution'] = e_s[:,0]
F[Src, 'e_pySolution'] = e_s[:,1]
# Note curl e = -iwb so b = -curl/iw
if self.verbose:
print('Ran for {:f} seconds'.format(time.time()-startTime))
sys.stdout.flush()
Ainv.clean()
return F
+7
View File
@@ -0,0 +1,7 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .Probs import eForm_ps
+21 -15
View File
@@ -1,19 +1,25 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from SimPEG import Utils, Problem, Maps, np, sp, mkvc from SimPEG import Utils, Problem, Maps, np, sp, mkvc
from SimPEG.EM.FDEM.SrcFDEM import BaseSrc as FDEMBaseSrc from SimPEG.EM.FDEM.SrcFDEM import BaseSrc as FDEMBaseSrc
from SimPEG.EM.Utils import omega from SimPEG.EM.Utils import omega
from scipy.constants import mu_0 from scipy.constants import mu_0
from numpy.lib import recfunctions as recFunc from numpy.lib import recfunctions as recFunc
from Utils.sourceUtils import homo1DModelSource from .Utils.sourceUtils import homo1DModelSource
from Utils import rec2ndarr from .Utils import rec2ndarr
import sys import sys
################# #################
### Sources ### ### Sources ###
################# #################
class BaseNSEMSrc(FDEMBaseSrc): class BaseMTSrc(FDEMBaseSrc):
''' '''
Sources for the NSEM problem. Sources for the MT problem.
Use the SimPEG BaseSrc, since the source fields share properties with the transmitters. Use the SimPEG BaseSrc, since the source fields share properties with the transmitters.
:param float freq: The frequency of the source :param float freq: The frequency of the source
@@ -29,28 +35,28 @@ class BaseNSEMSrc(FDEMBaseSrc):
FDEMBaseSrc.__init__(self, rxList) FDEMBaseSrc.__init__(self, rxList)
# 1D sources # 1D sources
class polxy_1DhomotD(BaseNSEMSrc): class polxy_1DhomotD(BaseMTSrc):
""" """
NSEM source for both polarizations (x and y) for the total Domain. MT source for both polarizations (x and y) for the total Domain.
It calculates fields calculated based on conditions on the boundary of the domain. It calculates fields calculated based on conditions on the boundary of the domain.
""" """
def __init__(self, rxList, freq): def __init__(self, rxList, freq):
BaseNSEMSrc.__init__(self, rxList, freq) BaseMTSrc.__init__(self, rxList, freq)
# TODO: need to add the primary fields calc and source terms into the problem. # TODO: need to add the primary fields calc and source terms into the problem.
# Need to implement such that it works for all dims. # Need to implement such that it works for all dims.
class polxy_1Dprimary(BaseNSEMSrc): class polxy_1Dprimary(BaseMTSrc):
""" """
NSEM source for both polarizations (x and y) given a 1D primary models. MT source for both polarizations (x and y) given a 1D primary models.
It assigns fields calculated from the 1D model as fields in the full space of the problem. It assigns fields calculated from the 1D model as fields in the full space of the problem.
""" """
def __init__(self, rxList, freq): def __init__(self, rxList, freq):
# assert mkvc(self.mesh.hz.shape,1) == mkvc(sigma1d.shape,1),'The number of values in the 1D background model does not match the number of vertical cells (hz).' # assert mkvc(self.mesh.hz.shape,1) == mkvc(sigma1d.shape,1),'The number of values in the 1D background model does not match the number of vertical cells (hz).'
self.sigma1d = None self.sigma1d = None
BaseNSEMSrc.__init__(self, rxList, freq) BaseMTSrc.__init__(self, rxList, freq)
# Hidden property of the ePrimary # Hidden property of the ePrimary
self._ePrimary = None self._ePrimary = None
@@ -78,7 +84,7 @@ class polxy_1Dprimary(BaseNSEMSrc):
C = problem.mesh.nodalGrad C = problem.mesh.nodalGrad
elif problem.mesh.dim == 3: elif problem.mesh.dim == 3:
C = problem.mesh.edgeCurl C = problem.mesh.edgeCurl
bBG_bp = (- C * self.ePrimary(problem) )*(1/( 1j*omega(self.freq) )) bBG_bp = (- C * self.ePrimary(problem) )*(1/(1j*omega(self.freq)))
return bBG_bp return bBG_bp
def S_e(self,problem): def S_e(self,problem):
@@ -128,15 +134,15 @@ class polxy_1Dprimary(BaseNSEMSrc):
# v should be nC size # v should be nC size
return MsigmaDeriv * v return MsigmaDeriv * v
class polxy_3Dprimary(BaseNSEMSrc): class polxy_3Dprimary(BaseMTSrc):
""" """
NSEM source for both polarizations (x and y) given a 3D primary model. It assigns fields calculated from the 1D model MT source for both polarizations (x and y) given a 3D primary model. It assigns fields calculated from the 1D model
as fields in the full space of the problem. as fields in the full space of the problem.
""" """
def __init__(self, rxList, freq): def __init__(self, rxList, freq):
# assert mkvc(self.mesh.hz.shape,1) == mkvc(sigma1d.shape,1),'The number of values in the 1D background model does not match the number of vertical cells (hz).' # assert mkvc(self.mesh.hz.shape,1) == mkvc(sigma1d.shape,1),'The number of values in the 1D background model does not match the number of vertical cells (hz).'
self.sigmaPrimary = None self.sigmaPrimary = None
BaseNSEMSrc.__init__(self, rxList, freq) BaseMTSrc.__init__(self, rxList, freq)
# Hidden property of the ePrimary # Hidden property of the ePrimary
self._ePrimary = None self._ePrimary = None
@@ -155,7 +161,7 @@ class polxy_3Dprimary(BaseNSEMSrc):
C = problem.mesh.nodalGrad C = problem.mesh.nodalGrad
elif problem.mesh.dim == 3: elif problem.mesh.dim == 3:
C = problem.mesh.edgeCurl C = problem.mesh.edgeCurl
bBG_bp = (- C * self.ePrimary(problem) )*(1/( 1j*omega(self.freq) )) bBG_bp = (- C * self.ePrimary(problem) )*(1/(1j*omega(self.freq)))
return bBG_bp return bBG_bp
def S_e(self,problem): def S_e(self,problem):
@@ -1,10 +1,16 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from SimPEG import Survey as SimPEGsurvey, Utils, Problem, Maps, np, sp, mkvc from SimPEG import Survey as SimPEGsurvey, Utils, Problem, Maps, np, sp, mkvc
from SimPEG.EM.FDEM.SrcFDEM import BaseSrc as FDEMBaseSrc from SimPEG.EM.FDEM.SrcFDEM import BaseSrc as FDEMBaseSrc
from SimPEG.EM.Utils import omega from SimPEG.EM.Utils import omega
from scipy.constants import mu_0 from scipy.constants import mu_0
from numpy.lib import recfunctions as recFunc from numpy.lib import recfunctions as recFunc
from Utils import rec2ndarr from .Utils import rec2ndarr
import SrcNSEM from . import SrcMT
import sys import sys
################# #################
@@ -63,9 +69,9 @@ class Rx(SimPEGsurvey.BaseRx):
''' '''
Project the fields to natural source data. Project the fields to natural source data.
:param SrcNSEM src: The source of the fields to project :param SrcMT src: The source of the fields to project
:param SimPEG.Mesh mesh: :param SimPEG.Mesh mesh:
:param FieldsNSEM f: Natural source fields object to project :param FieldsMT f: Natural source fields object to project
''' '''
## NOTE: Assumes that e is on t ## NOTE: Assumes that e is on t
@@ -76,7 +82,7 @@ class Rx(SimPEGsurvey.BaseRx):
bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0 bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0
# Note: Has a minus sign in front, to comply with quadrant calculations. # Note: Has a minus sign in front, to comply with quadrant calculations.
# Can be derived from zyx case for the 3D case. # Can be derived from zyx case for the 3D case.
f_part_complex = -ex/bx f_part_complex = old_div(-ex,bx)
# elif self.projType is 'Z2D': # elif self.projType is 'Z2D':
elif self.projType is 'Z3D': elif self.projType is 'Z3D':
## NOTE: Assumes that e is on edges and b on the faces. Need to generalize that or use a prop of fields to determine that. ## NOTE: Assumes that e is on edges and b on the faces. Need to generalize that or use a prop of fields to determine that.
@@ -103,13 +109,13 @@ class Rx(SimPEGsurvey.BaseRx):
hy_py = Pby*f[src,'b_py']/mu_0 hy_py = Pby*f[src,'b_py']/mu_0
# Make the complex data # Make the complex data
if 'zxx' in self.rxType: if 'zxx' in self.rxType:
f_part_complex = ( ex_px*hy_py - ex_py*hy_px)/(hx_px*hy_py - hx_py*hy_px) f_part_complex = old_div(( ex_px*hy_py - ex_py*hy_px),(hx_px*hy_py - hx_py*hy_px))
elif 'zxy' in self.rxType: elif 'zxy' in self.rxType:
f_part_complex = (-ex_px*hx_py + ex_py*hx_px)/(hx_px*hy_py - hx_py*hy_px) f_part_complex = old_div((-ex_px*hx_py + ex_py*hx_px),(hx_px*hy_py - hx_py*hy_px))
elif 'zyx' in self.rxType: elif 'zyx' in self.rxType:
f_part_complex = ( ey_px*hy_py - ey_py*hy_px)/(hx_px*hy_py - hx_py*hy_px) f_part_complex = old_div(( ey_px*hy_py - ey_py*hy_px),(hx_px*hy_py - hx_py*hy_px))
elif 'zyy' in self.rxType: elif 'zyy' in self.rxType:
f_part_complex = (-ey_px*hx_py + ey_py*hx_px)/(hx_px*hy_py - hx_py*hy_px) f_part_complex = old_div((-ey_px*hx_py + ey_py*hx_px),(hx_px*hy_py - hx_py*hy_px))
elif self.projType is 'T3D': elif self.projType is 'T3D':
if self.locs.ndim == 3: if self.locs.ndim == 3:
horLoc = self.locs[:,:,0] horLoc = self.locs[:,:,0]
@@ -127,9 +133,9 @@ class Rx(SimPEGsurvey.BaseRx):
by_py = Pby*f[src,'b_py'] by_py = Pby*f[src,'b_py']
bz_py = Pbz*f[src,'b_py'] bz_py = Pbz*f[src,'b_py']
if 'tzx' in self.rxType: if 'tzx' in self.rxType:
f_part_complex = (- by_px*bz_py + by_py*bz_px)/(bx_px*by_py - bx_py*by_px) f_part_complex = old_div((- by_px*bz_py + by_py*bz_px),(bx_px*by_py - bx_py*by_px))
if 'tzy' in self.rxType: if 'tzy' in self.rxType:
f_part_complex = ( bx_px*bz_py - bx_py*bz_px)/(bx_px*by_py - bx_py*by_px) f_part_complex = old_div(( bx_px*bz_py - bx_py*bz_px),(bx_px*by_py - bx_py*by_px))
else: else:
NotImplementedError('Projection of {:s} receiver type is not implemented.'.format(self.rxType)) NotImplementedError('Projection of {:s} receiver type is not implemented.'.format(self.rxType))
@@ -143,9 +149,9 @@ class Rx(SimPEGsurvey.BaseRx):
""" """
The derivative of the projection wrt u The derivative of the projection wrt u
:param NSEMsrc src: NSEM source :param MTsrc src: MT source
:param TensorMesh mesh: Mesh defining the topology of the problem :param TensorMesh mesh: Mesh defining the topology of the problem
:param NSEMfields f: NSEM fields object of the source :param MTfields f: MT fields object of the source
:param numpy.ndarray v: Random vector of size :param numpy.ndarray v: Random vector of size
""" """
@@ -157,8 +163,8 @@ class Rx(SimPEGsurvey.BaseRx):
Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex') Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex')
# ex = Pex*mkvc(f[src,'e_1d'],2) # ex = Pex*mkvc(f[src,'e_1d'],2)
# bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0 # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0
dP_de = -mkvc(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Pex*v),2) dP_de = -mkvc(Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))*(Pex*v),2)
dP_db = mkvc( Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))*(Pbx*f._bDeriv_u(src,v)/mu_0),2) dP_db = mkvc( Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2))*(Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))).T*Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))))*(Pbx*f._bDeriv_u(src,v)/mu_0),2)
PDeriv_complex = np.sum(np.hstack((dP_de,dP_db)),1) PDeriv_complex = np.sum(np.hstack((dP_de,dP_db)),1)
elif self.projType is 'Z2D': elif self.projType is 'Z2D':
raise NotImplementedError('Has not been implement for 2D impedance tensor') raise NotImplementedError('Has not been implement for 2D impedance tensor')
@@ -198,7 +204,7 @@ class Rx(SimPEGsurvey.BaseRx):
# Update the input vector # Update the input vector
sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sDiag = lambda t: Utils.sdiag(mkvc(t,2))
# Define the components of the derivative # Define the components of the derivative
Hd = sDiag(1./(sDiag(hx_px)*hy_py - sDiag(hx_py)*hy_px)) Hd = sDiag(old_div(1.,(sDiag(hx_px)*hy_py - sDiag(hx_py)*hy_px)))
Hd_uV = sDiag(hy_py)*hx_px_u(v) + sDiag(hx_px)*hy_py_u(v) - sDiag(hx_py)*hy_px_u(v) - sDiag(hy_px)*hx_py_u(v) Hd_uV = sDiag(hy_py)*hx_px_u(v) + sDiag(hx_px)*hy_py_u(v) - sDiag(hx_py)*hy_px_u(v) - sDiag(hy_px)*hx_py_u(v)
# Calculate components # Calculate components
if 'zxx' in self.rxType: if 'zxx' in self.rxType:
@@ -247,7 +253,7 @@ class Rx(SimPEGsurvey.BaseRx):
# Update the input vector # Update the input vector
sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sDiag = lambda t: Utils.sdiag(mkvc(t,2))
# Define the components of the derivative # Define the components of the derivative
Hd = sDiag(1./(sDiag(bx_px)*by_py - sDiag(bx_py)*by_px)) Hd = sDiag(old_div(1.,(sDiag(bx_px)*by_py - sDiag(bx_py)*by_px)))
Hd_uV = sDiag(by_py)*bx_px_u(v) + sDiag(bx_px)*by_py_u(v) - sDiag(bx_py)*by_px_u(v) - sDiag(by_px)*bx_py_u(v) Hd_uV = sDiag(by_py)*bx_px_u(v) + sDiag(bx_px)*by_py_u(v) - sDiag(bx_py)*by_px_u(v) - sDiag(by_px)*bx_py_u(v)
if 'tzx' in self.rxType: if 'tzx' in self.rxType:
Tij = sDiag(Hd*( - sDiag(by_px)*bz_py + sDiag(by_py)*bz_px )) Tij = sDiag(Hd*( - sDiag(by_px)*bz_py + sDiag(by_py)*bz_px ))
@@ -267,8 +273,8 @@ class Rx(SimPEGsurvey.BaseRx):
Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex') Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex')
# ex = Pex*mkvc(f[src,'e_1d'],2) # ex = Pex*mkvc(f[src,'e_1d'],2)
# bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0 # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0
dP_deTv = -mkvc(Pex.T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*v,2) dP_deTv = -mkvc(Pex.T*Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))).T*v,2)
db_duv = Pbx.T/mu_0*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))).T*Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2)).T*v db_duv = Pbx.T/mu_0*Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))*(Utils.sdiag(old_div(1.,(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))).T*Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2)).T*v
dP_dbTv = mkvc(f._bDeriv_u(src,db_duv,adjoint=True),2) dP_dbTv = mkvc(f._bDeriv_u(src,db_duv,adjoint=True),2)
PDeriv_real = np.sum(np.hstack((dP_deTv,dP_dbTv)),1) PDeriv_real = np.sum(np.hstack((dP_deTv,dP_dbTv)),1)
elif self.projType is 'Z2D': elif self.projType is 'Z2D':
@@ -300,17 +306,17 @@ class Rx(SimPEGsurvey.BaseRx):
aey_px_u = lambda vec: f._e_pxDeriv_u(src,Pey.T*vec,adjoint=True) aey_px_u = lambda vec: f._e_pxDeriv_u(src,Pey.T*vec,adjoint=True)
aex_py_u = lambda vec: f._e_pyDeriv_u(src,Pex.T*vec,adjoint=True) aex_py_u = lambda vec: f._e_pyDeriv_u(src,Pex.T*vec,adjoint=True)
aey_py_u = lambda vec: f._e_pyDeriv_u(src,Pey.T*vec,adjoint=True) aey_py_u = lambda vec: f._e_pyDeriv_u(src,Pey.T*vec,adjoint=True)
ahx_px_u = lambda vec: f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0 ahx_px_u = lambda vec: old_div(f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True),mu_0)
ahy_px_u = lambda vec: f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0 ahy_px_u = lambda vec: old_div(f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True),mu_0)
ahx_py_u = lambda vec: f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0 ahx_py_u = lambda vec: old_div(f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True),mu_0)
ahy_py_u = lambda vec: f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0 ahy_py_u = lambda vec: old_div(f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True),mu_0)
# Update the input vector # Update the input vector
# Define shortcuts # Define shortcuts
sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sDiag = lambda t: Utils.sdiag(mkvc(t,2))
sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2)) sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2))
# Define the components of the derivative # Define the components of the derivative
aHd = sDiag(1./(sDiag(ahx_px)*ahy_py - sDiag(ahx_py)*ahy_px)) aHd = sDiag(old_div(1.,(sDiag(ahx_px)*ahy_py - sDiag(ahx_py)*ahy_px)))
aHd_uV = lambda x: ahx_px_u(sDiag(ahy_py)*x) + ahx_px_u(sDiag(ahy_py)*x) - ahy_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(ahy_px)*x) aHd_uV = lambda x: ahx_px_u(sDiag(ahy_py)*x) + ahx_px_u(sDiag(ahy_py)*x) - ahy_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(ahy_px)*x)
# Need to fix this to reflect the adjoint # Need to fix this to reflect the adjoint
if 'zxx' in self.rxType: if 'zxx' in self.rxType:
@@ -362,7 +368,7 @@ class Rx(SimPEGsurvey.BaseRx):
sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sDiag = lambda t: Utils.sdiag(mkvc(t,2))
sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2)) sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2))
# Define the components of the derivative # Define the components of the derivative
aHd = sDiag(1./(sDiag(abx_px)*aby_py - sDiag(abx_py)*aby_px)) aHd = sDiag(old_div(1.,(sDiag(abx_px)*aby_py - sDiag(abx_py)*aby_px)))
aHd_uV = lambda x: abx_px_u(sDiag(aby_py)*x) + abx_px_u(sDiag(aby_py)*x) - aby_px_u(sDiag(abx_py)*x) - abx_py_u(sDiag(aby_px)*x) aHd_uV = lambda x: abx_px_u(sDiag(aby_py)*x) + abx_px_u(sDiag(aby_py)*x) - aby_px_u(sDiag(abx_py)*x) - abx_py_u(sDiag(aby_px)*x)
# Need to fix this to reflect the adjoint # Need to fix this to reflect the adjoint
if 'tzx' in self.rxType: if 'tzx' in self.rxType:
@@ -390,12 +396,12 @@ class Rx(SimPEGsurvey.BaseRx):
################# #################
class Survey(SimPEGsurvey.BaseSurvey): class Survey(SimPEGsurvey.BaseSurvey):
""" """
Survey class for NSEM. Contains all the sources associated with the survey. Survey class for MT. Contains all the sources associated with the survey.
:param list srcList: List of sources associated with the survey :param list srcList: List of sources associated with the survey
""" """
srcPair = SrcNSEM.BaseNSEMSrc srcPair = SrcMT.BaseMTSrc
def __init__(self, srcList, **kwargs): def __init__(self, srcList, **kwargs):
# Sort these by frequency # Sort these by frequency
@@ -443,7 +449,7 @@ class Survey(SimPEGsurvey.BaseSurvey):
################# #################
class Data(SimPEGsurvey.Data): class Data(SimPEGsurvey.Data):
''' '''
Data class for NSEMdata. Stores the data vector indexed by the survey. Data class for MTdata. Stores the data vector indexed by the survey.
:param SimPEG survey object survey: :param SimPEG survey object survey:
:param v vector of the data in order matching of the survey :param v vector of the data in order matching of the survey
@@ -461,7 +467,7 @@ class Data(SimPEGsurvey.Data):
def toRecArray(self,returnType='RealImag'): def toRecArray(self,returnType='RealImag'):
''' '''
Function that returns a numpy.recarray for a SimpegNSEM impedance data object. Function that returns a numpy.recarray for a SimpegMT impedance data object.
:param str returnType: Switches between returning a rec array where the impedance is split to real and imaginary ('RealImag') or is a complex ('Complex') :param str returnType: Switches between returning a rec array where the impedance is split to real and imaginary ('RealImag') or is a complex ('Complex')
@@ -483,7 +489,7 @@ class Data(SimPEGsurvey.Data):
locs = np.hstack((np.array([[0.0]]),locs)) locs = np.hstack((np.array([[0.0]]),locs))
tArrRec = np.concatenate((src.freq*np.ones((locs.shape[0],1)),locs,np.nan*np.ones((locs.shape[0],12))),axis=1).view(dtRI) tArrRec = np.concatenate((src.freq*np.ones((locs.shape[0],1)),locs,np.nan*np.ones((locs.shape[0],12))),axis=1).view(dtRI)
# np.array([(src.freq,rx.locs[0,0],rx.locs[0,1],rx.locs[0,2],np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ) for rx in src.rxList],dtype=dtRI) # np.array([(src.freq,rx.locs[0,0],rx.locs[0,1],rx.locs[0,2],np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ) for rx in src.rxList],dtype=dtRI)
# Get the type and the value for the DataNSEM object as a list # Get the type and the value for the DataMT object as a list
typeList = [[rx.rxType.replace('z1d','zyx'),self[src,rx]] for rx in src.rxList] typeList = [[rx.rxType.replace('z1d','zyx'),self[src,rx]] for rx in src.rxList]
# Insert the values to the temp array # Insert the values to the temp array
for nr,(key,val) in enumerate(typeList): for nr,(key,val) in enumerate(typeList):
@@ -517,17 +523,17 @@ class Data(SimPEGsurvey.Data):
@classmethod @classmethod
def fromRecArray(cls, recArray, srcType='primary'): def fromRecArray(cls, recArray, srcType='primary'):
""" """
Class method that reads in a numpy record array to NSEMdata object. Class method that reads in a numpy record array to MTdata object.
Only imports the impedance data. Only imports the impedance data.
""" """
if srcType=='primary': if srcType=='primary':
src = SrcNSEM.polxy_1Dprimary src = SrcMT.polxy_1Dprimary
elif srcType=='total': elif srcType=='total':
src = SrcNSEM.polxy_1DhomotD src = SrcMT.polxy_1DhomotD
else: else:
raise NotImplementedError('{:s} is not a valid source type for NSEMdata') raise NotImplementedError('{:s} is not a valid source type for MTdata')
# Find all the frequencies in recArray # Find all the frequencies in recArray
uniFreq = np.unique(recArray['freq']) uniFreq = np.unique(recArray['freq'])
@@ -1,9 +1,16 @@
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from future import standard_library
standard_library.install_aliases()
from builtins import zip
# Analytic solution of EM fields due to a plane wave # Analytic solution of EM fields due to a plane wave
import numpy as np, SimPEG as simpeg import numpy as np, SimPEG as simpeg
from scipy.constants import mu_0, epsilon_0 as eps_0 from scipy.constants import mu_0, epsilon_0 as eps_0
def getEHfields(m1d,sigma,freq,zd,scaleUD=True,scaleValue=1): def getEHfields(m1d,sigma,freq,zd,scaleUD=True):
'''Analytic solution for MT 1D layered earth. Returns E and H fields. '''Analytic solution for MT 1D layered earth. Returns E and H fields.
:param SimPEG.mesh, object m1d: Mesh object with the 1D spatial information. :param SimPEG.mesh, object m1d: Mesh object with the 1D spatial information.
@@ -12,7 +19,7 @@ def getEHfields(m1d,sigma,freq,zd,scaleUD=True,scaleValue=1):
:param numpy array, vector zd: location to calculate EH fields at :param numpy array, vector zd: location to calculate EH fields at
:param bollean, scaleUD: scales the output to be 1 at the top, increases numeracal stability. :param bollean, scaleUD: scales the output to be 1 at the top, increases numeracal stability.
Assumes a halfspace with the same conductive as the deepest cell. Assumes a halfspace with the same conductive as the last cell below.
''' '''
# Note add an error check for the mesh and sigma are the same size. # Note add an error check for the mesh and sigma are the same size.
@@ -29,18 +36,18 @@ def getEHfields(m1d,sigma,freq,zd,scaleUD=True,scaleValue=1):
# Initiate the propagation matrix, in the order down up. # Initiate the propagation matrix, in the order down up.
UDp = np.zeros((2,m1d.nC+1),dtype=complex) UDp = np.zeros((2,m1d.nC+1),dtype=complex)
UDp[1,0] = scaleValue # Set the wave amplitude as 1 into the half-space at the bottom of the mesh UDp[1,0] = 1. # Set the wave amplitude as 1 into the half-space at the bottom of the mesh
# Loop over all the layers, starting at the bottom layer # Loop over all the layers, starting at the bottom layer
for lnr, h in enumerate(m1d.hx): # lnr-number of layer, h-thickness of the layer for lnr, h in enumerate(m1d.hx): # lnr-number of layer, h-thickness of the layer
# Calculate # Calculate
yp1 = k[lnr]/(w*mu[lnr]) # Admittance of the layer below the current layer yp1 = old_div(k[lnr],(w*mu[lnr])) # Admittance of the layer below the current layer
zp = (w*mu[lnr+1])/k[lnr+1] # Impedance in the current layer zp = old_div((w*mu[lnr+1]),k[lnr+1]) # Impedance in the current layer
# Build the propagation matrix # Build the propagation matrix
# Convert fields to down/up going components in layer below current layer # Convert fields to down/up going components in layer below current layer
Pj1 = np.array([[1,1],[yp1,-yp1]],dtype=complex) Pj1 = np.array([[1,1],[yp1,-yp1]])
# Convert fields to down/up going components in current layer # Convert fields to down/up going components in current layer
Pjinv = 1./2*np.array([[1,zp],[1,-zp]],dtype=complex) Pjinv = 1./2*np.array([[1,zp],[1,-zp]])
# Propagate down and up components through the current layer # Propagate down and up components through the current layer
elamh = np.array([[np.exp(-1j*k[lnr+1]*h),0],[0,np.exp(1j*k[lnr+1]*h)]]) elamh = np.array([[np.exp(-1j*k[lnr+1]*h),0],[0,np.exp(1j*k[lnr+1]*h)]])
@@ -48,14 +55,7 @@ def getEHfields(m1d,sigma,freq,zd,scaleUD=True,scaleValue=1):
UDp[:,lnr+1] = elamh.dot(Pjinv.dot(Pj1)).dot(UDp[:,lnr]) UDp[:,lnr+1] = elamh.dot(Pjinv.dot(Pj1)).dot(UDp[:,lnr])
if scaleUD: if scaleUD:
# Scale the values such that 1 at the top UDp[:,lnr+1::-1] = old_div(UDp[:,lnr+1::-1],UDp[1,lnr+1])
scaleVal = UDp[:,lnr+1::-1]/UDp[1,lnr+1]
if np.any(np.isnan(scaleVal)):
# If there is a nan (thickness very great), rebuild the move up cell
scaleVal = np.zeros_like(UDp[:,lnr+1::-1],dtype=complex)
scaleVal[1,0] = scaleValue
UDp[:,lnr+1::-1] = scaleVal
# Calculate the fields # Calculate the fields
Ed = np.empty((zd.size,),dtype=complex) Ed = np.empty((zd.size,),dtype=complex)
@@ -69,14 +69,14 @@ def getEHfields(m1d,sigma,freq,zd,scaleUD=True,scaleValue=1):
dind = dup >= zd dind = dup >= zd
Ed[dind] = UDp[1,0]*np.exp(-1j*k[0]*(dup-zd[dind])) Ed[dind] = UDp[1,0]*np.exp(-1j*k[0]*(dup-zd[dind]))
Eu[dind] = UDp[0,0]*np.exp(1j*k[0]*(dup-zd[dind])) Eu[dind] = UDp[0,0]*np.exp(1j*k[0]*(dup-zd[dind]))
Hd[dind] = (k[0]/(w*mu[0]))*UDp[1,0]*np.exp(-1j*k[0]*(dup-zd[dind])) Hd[dind] = (old_div(k[0],(w*mu[0])))*UDp[1,0]*np.exp(-1j*k[0]*(dup-zd[dind]))
Hu[dind] = -(k[0]/(w*mu[0]))*UDp[0,0]*np.exp(1j*k[0]*(dup-zd[dind])) Hu[dind] = -(old_div(k[0],(w*mu[0])))*UDp[0,0]*np.exp(1j*k[0]*(dup-zd[dind]))
for ki,mui,epsi,dlow,dup,Up,Dp in zip(k[1::],mu[1::],eps[1::],m1d.vectorNx[:-1],m1d.vectorNx[1::],UDp[0,1::],UDp[1,1::]): for ki,mui,epsi,dlow,dup,Up,Dp in zip(k[1::],mu[1::],eps[1::],m1d.vectorNx[:-1],m1d.vectorNx[1::],UDp[0,1::],UDp[1,1::]):
dind = np.logical_and(dup >= zd, zd > dlow) dind = np.logical_and(dup >= zd, zd > dlow)
Ed[dind] = Dp*np.exp(-1j*ki*(dup-zd[dind])) Ed[dind] = Dp*np.exp(-1j*ki*(dup-zd[dind]))
Eu[dind] = Up*np.exp(1j*ki*(dup-zd[dind])) Eu[dind] = Up*np.exp(1j*ki*(dup-zd[dind]))
Hd[dind] = (ki/(w*mui))*Dp*np.exp(-1j*ki*(dup-zd[dind])) Hd[dind] = (old_div(ki,(w*mui)))*Dp*np.exp(-1j*ki*(dup-zd[dind]))
Hu[dind] = -(ki/(w*mui))*Up*np.exp(1j*ki*(dup-zd[dind])) Hu[dind] = -(old_div(ki,(w*mui)))*Up*np.exp(1j*ki*(dup-zd[dind]))
# Return return the fields # Return return the fields
return Ed, Eu, Hd, Hu return Ed, Eu, Hd, Hu
@@ -99,15 +99,15 @@ def getImpedance(m1d,sigma,freq):
om = 2*np.pi*fr om = 2*np.pi*fr
Zall = np.empty(len(h)+1,dtype='complex') Zall = np.empty(len(h)+1,dtype='complex')
# Calculate the impedance for the bottom layer # Calculate the impedance for the bottom layer
Zall[0] = (mu_0*om)/np.sqrt(mu_0*eps_0*(om)**2 - 1j*mu_0*sigma[0]*om) Zall[0] = old_div((mu_0*om),np.sqrt(mu_0*eps_0*(om)**2 - 1j*mu_0*sigma[0]*om))
for nr,hi in enumerate(h): for nr,hi in enumerate(h):
# Calculate the wave number # Calculate the wave number
# print nr,sigma[nr] # print nr,sigma[nr]
k = np.sqrt(mu_0*eps_0*om**2 - 1j*mu_0*sigma[nr]*om) k = np.sqrt(mu_0*eps_0*om**2 - 1j*mu_0*sigma[nr]*om)
Z = (mu_0*om)/k Z = old_div((mu_0*om),k)
Zall[nr+1] = Z *((Zall[nr] + Z*np.tanh(1j*k*hi))/(Z + Zall[nr]*np.tanh(1j*k*hi))) Zall[nr+1] = Z *(old_div((Zall[nr] + Z*np.tanh(1j*k*hi)),(Z + Zall[nr]*np.tanh(1j*k*hi))))
#pdb.set_trace() #pdb.set_trace()
Z1d[nrFr] = Zall[-1] Z1d[nrFr] = Zall[-1]
@@ -1,5 +1,11 @@
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
import numpy as np, SimPEG as simpeg import numpy as np, SimPEG as simpeg
from MT1Danalytic import getEHfields from .MT1Danalytic import getEHfields
from scipy.constants import mu_0 from scipy.constants import mu_0
def get1DEfields(m1d,sigma,freq,sourceAmp=1.0): def get1DEfields(m1d,sigma,freq,sourceAmp=1.0):
@@ -9,7 +15,7 @@ def get1DEfields(m1d,sigma,freq,sourceAmp=1.0):
G = m1d.nodalGrad G = m1d.nodalGrad
# Mass matrices # Mass matrices
# Magnetic permeability # Magnetic permeability
Mmu = simpeg.Utils.sdiag(m1d.vol*(1.0/mu_0)) Mmu = simpeg.Utils.sdiag(m1d.vol*(old_div(1.0,mu_0)))
# Conductivity # Conductivity
Msig = m1d.getFaceInnerProduct(sigma) Msig = m1d.getFaceInnerProduct(sigma)
# Set up the solution matrix # Set up the solution matrix
@@ -23,7 +29,7 @@ def get1DEfields(m1d,sigma,freq,sourceAmp=1.0):
Ed, Eu, Hd, Hu = getEHfields(m1d,sigma,freq,m1d.vectorNx) Ed, Eu, Hd, Hu = getEHfields(m1d,sigma,freq,m1d.vectorNx)
Etot = (Ed + Eu) Etot = (Ed + Eu)
if sourceAmp is not None: if sourceAmp is not None:
Etot = ((Etot/Etot[-1])*sourceAmp) # Scale the fields to be equal to sourceAmp at the top Etot = ((old_div(Etot,Etot[-1]))*sourceAmp) # Scale the fields to be equal to sourceAmp at the top
## Note: The analytic solution is derived with e^iwt ## Note: The analytic solution is derived with e^iwt
bc = np.r_[Etot[0],Etot[-1]] bc = np.r_[Etot[0],Etot[-1]]
# The right hand side # The right hand side
+10
View File
@@ -0,0 +1,10 @@
from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import division
from future import standard_library
standard_library.install_aliases()
from .MT1Dsolutions import * # Add the names of the functions
from .MT1Danalytic import *
from .dataUtils import *
from .ediFilesUtils import *
@@ -1,3 +1,9 @@
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
# Utils used for the data, # Utils used for the data,
import numpy as np, matplotlib.pyplot as plt, sys import numpy as np, matplotlib.pyplot as plt, sys
import SimPEG as simpeg import SimPEG as simpeg
@@ -5,25 +11,25 @@ import numpy.lib.recfunctions as recFunc
from scipy.constants import mu_0 from scipy.constants import mu_0
from scipy import interpolate as sciint from scipy import interpolate as sciint
def getAppRes(NSEMdata): def getAppRes(MTdata):
# Make impedance # Make impedance
zList = [] zList = []
for src in NSEMdata.survey.srcList: for src in MTdata.survey.srcList:
zc = [src.freq] zc = [src.freq]
for rx in src.rxList: for rx in src.rxList:
if 'i' in rx.rxType: if 'i' in rx.rxType:
m=1j m=1j
else: else:
m = 1 m = 1
zc.append(m*NSEMdata[src,rx]) zc.append(m*MTdata[src,rx])
zList.append(zc) zList.append(zc)
return [appResPhs(zList[i][0],np.sum(zList[i][1:3])) for i in np.arange(len(zList))] return [appResPhs(zList[i][0],np.sum(zList[i][1:3])) for i in np.arange(len(zList))]
def rotateData(NSEMdata,rotAngle): def rotateData(MTdata, rotAngle):
''' '''
Function that rotates clockwist by rotAngle (- negative for a counter-clockwise rotation) Function that rotates clockwist by rotAngle (- negative for a counter-clockwise rotation)
''' '''
recData = NSEMdata.toRecArray('Complex') recData = MTdata.toRecArray('Complex')
impData = rec2ndarr(recData[['zxx','zxy','zyx','zyy']],complex) impData = rec2ndarr(recData[['zxx','zxy','zyx','zyy']],complex)
# Make the rotation matrix # Make the rotation matrix
# c,s,zxx,zxy,zyx,zyy = sympy.symbols('c,s,zxx,zxy,zyx,zyy') # c,s,zxx,zxy,zyx,zyy = sympy.symbols('c,s,zxx,zxy,zyx,zyy')
@@ -40,38 +46,38 @@ def rotateData(NSEMdata,rotAngle):
for nr,comp in enumerate(['zxx','zxy','zyx','zyy']): for nr,comp in enumerate(['zxx','zxy','zyx','zyy']):
outRec[comp] = rotData[:,nr] outRec[comp] = rotData[:,nr]
from SimPEG import NSEM from SimPEG import MT
return NSEM.Data.fromRecArray(outRec) return MT.Data.fromRecArray(outRec)
def appResPhs(freq,z): def appResPhs(freq, z):
app_res = ((1./(8e-7*np.pi**2))/freq)*np.abs(z)**2 app_res = (old_div((old_div(1.,(8e-7*np.pi**2))),freq))*np.abs(z)**2
app_phs = np.arctan2(z.imag,z.real)*(180/np.pi) app_phs = np.arctan2(z.imag,z.real)*(old_div(180,np.pi))
return app_res, app_phs return app_res, app_phs
def skindepth(rho,freq): def skindepth(rho, freq):
''' Function to calculate the skindepth of EM waves''' ''' Function to calculate the skindepth of EM waves'''
return np.sqrt( (rho*((1/(freq * mu_0 * np.pi ))))) return np.sqrt( (rho*((old_div(1,(freq * mu_0 * np.pi ))))))
def rec2ndarr(x,dt=float): def rec2ndarr(x, dt=float):
return x.view((dt, len(x.dtype.names))) return x.view((dt, len(x.dtype.names)))
def makeAnalyticSolution(mesh,model,elev,freqs): def makeAnalyticSolution(mesh, model, elev, freqs):
from SimPEG import NSEM from SimPEG import MT
data1D = [] data1D = []
for freq in freqs: for freq in freqs:
anaEd, anaEu, anaHd, anaHu = NSEM.Utils.MT1Danalytic.getEHfields(mesh,model,freq,elev) anaEd, anaEu, anaHd, anaHu = MT.Utils.MT1Danalytic.getEHfields(mesh,model,freq,elev)
anaE = anaEd+anaEu anaE = anaEd+anaEu
anaH = anaHd+anaHu anaH = anaHd+anaHu
anaZ = anaE/anaH anaZ = old_div(anaE,anaH)
# Add to the list # Add to the list
data1D.append((freq,0,0,elev,anaZ[0])) data1D.append((freq,0,0,elev,anaZ[0]))
dataRec = np.array(data1D,dtype=[('freq',float),('x',float),('y',float),('z',float),('zyx',complex)]) dataRec = np.array(data1D,dtype=[('freq',float),('x',float),('y',float),('z',float),('zyx',complex)])
return dataRec return dataRec
def plotMT1DModelData(problem,models,symList=None): def plotMT1DModelData(problem, models, symList=None):
from SimPEG import NSEM from SimPEG import MT
# Setup the figure # Setup the figure
fontSize = 15 fontSize = 15
@@ -79,7 +85,7 @@ def plotMT1DModelData(problem,models,symList=None):
axM = fig.add_axes([0.075,.1,.25,.875]) axM = fig.add_axes([0.075,.1,.25,.875])
axM.set_xlabel('Resistivity [Ohm*m]',fontsize=fontSize) axM.set_xlabel('Resistivity [Ohm*m]',fontsize=fontSize)
axM.set_xlim(1e-1,1e5) axM.set_xlim(1e-1,1e5)
# axM.set_ylim(-10000,5000) axM.set_ylim(-10000,5000)
axM.set_ylabel('Depth [km]',fontsize=fontSize) axM.set_ylabel('Depth [km]',fontsize=fontSize)
axR = fig.add_axes([0.42,.575,.5,.4]) axR = fig.add_axes([0.42,.575,.5,.4])
axR.set_xscale('log') axR.set_xscale('log')
@@ -97,7 +103,7 @@ def plotMT1DModelData(problem,models,symList=None):
# if not symList: # if not symList:
# symList = ['x']*len(models) # symList = ['x']*len(models)
import plotDataTypes as pDt from . import plotDataTypes as pDt
# Loop through the models. # Loop through the models.
modelList = [problem.survey.mtrue] modelList = [problem.survey.mtrue]
modelList.extend(models) modelList.extend(models)
@@ -110,14 +116,14 @@ def plotMT1DModelData(problem,models,symList=None):
else: else:
data1D = problem.dataPair(problem.survey,problem.survey.dpred(model)).toRecArray('Complex') data1D = problem.dataPair(problem.survey,problem.survey.dpred(model)).toRecArray('Complex')
# Plot the data and the model # Plot the data and the model
colRat = nr/((len(modelList)-1.999)*1.) colRat = old_div(nr,((len(modelList)-1.999)*1.))
if colRat > 1.: if colRat > 1.:
col = 'k' col = 'k'
else: else:
col = plt.cm.seismic(1-colRat) col = plt.cm.seismic(1-colRat)
# The model - make the pts to plot # The model - make the pts to plot
meshPts = np.concatenate((problem.mesh.gridN[0:1],np.kron(problem.mesh.gridN[1::],np.ones(2))[:-1])) meshPts = np.concatenate((problem.mesh.gridN[0:1],np.kron(problem.mesh.gridN[1::],np.ones(2))[:-1]))
modelPts = np.kron(1./(problem.mapping.sigmaMap*model),np.ones(2,)) modelPts = np.kron(old_div(1.,(problem.mapping.sigmaMap*model)),np.ones(2,))
axM.semilogx(modelPts,meshPts,color=col) axM.semilogx(modelPts,meshPts,color=col)
## Data ## Data
@@ -132,94 +138,38 @@ def plotMT1DModelData(problem,models,symList=None):
freq = simpeg.mkvc(data1D['freq'],2) freq = simpeg.mkvc(data1D['freq'],2)
res, phs = appResPhs(freq,allData) res, phs = appResPhs(freq,allData)
if False: stdCol = 'gray'
stdCol = 'gray' axRtw = axR.twinx()
axRtw = axR.twinx() axRtw.set_ylabel('Std of log10',color=stdCol)
axRtw.set_ylabel('Std of log10',color=stdCol) [(t.set_color(stdCol), t.set_rotation(-45)) for t in axRtw.get_yticklabels()]
[(t.set_color(stdCol), t.set_rotation(-45)) for t in axRtw.get_yticklabels()] axPtw = axP.twinx()
axPtw = axP.twinx() axPtw.set_ylabel('Std ',color=stdCol)
axPtw.set_ylabel('Std ',color=stdCol) [t.set_color(stdCol) for t in axPtw.get_yticklabels()]
[t.set_color(stdCol) for t in axPtw.get_yticklabels()] axRtw.plot(freq, np.std(np.log10(res),1),'--',color=stdCol)
axRtw.plot(freq, np.std(np.log10(res),1),'--',color=stdCol) axPtw.plot(freq, np.std(phs,1),'--',color=stdCol)
axPtw.plot(freq, np.std(phs,1),'--',color=stdCol)
# Fix labels and ticks # Fix labels and ticks
# yMtick = [l/1000 for l in axM.get_yticks().tolist()] yMtick = [old_div(l,1000) for l in axM.get_yticks().tolist()]
# axM.set_yticklabels(yMtick) axM.set_yticklabels(yMtick)
[ l.set_rotation(90) for l in axM.get_yticklabels()] [ l.set_rotation(90) for l in axM.get_yticklabels()]
[ l.set_rotation(90) for l in axR.get_yticklabels()] [ l.set_rotation(90) for l in axR.get_yticklabels()]
# [(t.set_color(stdCol), t.set_rotation(-45)) for t in axRtw.get_yticklabels()] [(t.set_color(stdCol), t.set_rotation(-45)) for t in axRtw.get_yticklabels()]
# [t.set_color(stdCol) for t in axPtw.get_yticklabels()] [t.set_color(stdCol) for t in axPtw.get_yticklabels()]
for ax in [axM,axR,axP]: for ax in [axM,axR,axP]:
ax.xaxis.set_tick_params(labelsize=fontSize) ax.xaxis.set_tick_params(labelsize=fontSize)
ax.yaxis.set_tick_params(labelsize=fontSize) ax.yaxis.set_tick_params(labelsize=fontSize)
return fig return fig
def plotImpAppRes(dataArrays,plotLoc,textStr=[]):
''' Plots amplitude impedance and phase'''
# fig = plt.figure(1,(7, 7))
import plotDataTypes as pDt
# axes = ImageGrid(fig, (0.05,0.05,0.875,0.875),nrows_ncols = (2, 2),axes_pad = 0.25,add_all=True,share_all=True,label_mode = "L")
# Make the figure and axes
fig,axT=plt.subplots(2,2,sharex=True)
axes = axT.ravel()
fig.set_size_inches((13.5,7.0))
fig.suptitle('{:s}\nStation at: {:.1f}x ; {:.1f}y'.format(textStr,plotLoc[0],plotLoc[1]))
# Have to deal with axes
# Set log
for ax in axes.ravel():
ax.set_xscale('log')
axes[0].invert_xaxis()
axes[0].set_yscale('log')
axes[2].set_yscale('log')
# Set labels
axes[2].set_xlabel('Frequency [Hz]')
axes[3].set_xlabel('Frequency [Hz]')
axes[0].set_ylabel('Apperent resistivity [Ohm m]')
axes[1].set_ylabel('Apperent phase [degrees]')
axes[1].set_ylim(-180,180)
axes[2].set_ylabel('Impedance amplitude [V/A]')
axes[3].set_ylim(-180,180)
axes[3].set_ylabel('Impedance angle [degrees]')
# Plot the data
for nr,dataArray in enumerate(dataArrays):
if nr==1:
parSym = '*'
else:
parSym = 's'
# app res
pDt.plotIsoStaImpedance(axes[0],plotLoc,dataArray,'zxy',par='res',pSym=parSym)
pDt.plotIsoStaImpedance(axes[0],plotLoc,dataArray,'zyx',par='res',pSym=parSym)
# app phs
pDt.plotIsoStaImpedance(axes[1],plotLoc,dataArray,'zxy',par='phs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[1],plotLoc,dataArray,'zyx',par='phs',pSym=parSym)
# imp abs
pDt.plotIsoStaImpedance(axes[2],plotLoc,dataArray,'zxx',par='abs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[2],plotLoc,dataArray,'zxy',par='abs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[2],plotLoc,dataArray,'zyx',par='abs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[2],plotLoc,dataArray,'zyy',par='abs',pSym=parSym)
# imp abs
pDt.plotIsoStaImpedance(axes[3],plotLoc,dataArray,'zxx',par='phs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[3],plotLoc,dataArray,'zxy',par='phs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[3],plotLoc,dataArray,'zyx',par='phs',pSym=parSym)
pDt.plotIsoStaImpedance(axes[3],plotLoc,dataArray,'zyy',par='phs',pSym=parSym)
return fig,axes
def printTime(): def printTime():
import time import time
print time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()) print(time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime()))
def convert3Dto1Dobject(NSEMdata,rxType3D='zyx'): def convert3Dto1Dobject(MTdata,rxType3D='zyx'):
from SimPEG import NSEM from SimPEG import MT
# Find the unique locations # Find the unique locations
# Need to find the locations # Need to find the locations
recDataTemp = NSEMdata.toRecArray() recDataTemp = MTdata.toRecArray()
# Check if survey.std has been assigned. # Check if survey.std has been assigned.
## NEED TO: write this... ## NEED TO: write this...
# Calculte and add the DET of the tensor to the recArray # Calculte and add the DET of the tensor to the recArray
@@ -241,24 +191,24 @@ def convert3Dto1Dobject(NSEMdata,rxType3D='zyx'):
# Make the receiver list # Make the receiver list
rx1DList = [] rx1DList = []
for rxType in ['z1dr','z1di']: for rxType in ['z1dr','z1di']:
rx1DList.append(NSEM.Rx(simpeg.mkvc(loc,2).T,rxType)) rx1DList.append(MT.Rx(simpeg.mkvc(loc,2).T,rxType))
# Source list # Source list
locrecData = recData[np.sqrt(np.sum( (rec2ndarr(recData[['x','y','z']]).data - loc )**2,axis=1)) < 1e-5] locrecData = recData[np.sqrt(np.sum( (rec2ndarr(recData[['x','y','z']]).data - loc )**2,axis=1)) < 1e-5]
dat1DList = [] dat1DList = []
src1DList = [] src1DList = []
for freq in locrecData['freq']: for freq in locrecData['freq']:
src1DList.append(NSEM.SrcNSEM.src_polxy_1Dprimary(rx1DList,freq)) src1DList.append(MT.SrcMT.src_polxy_1Dprimary(rx1DList,freq))
for comp in ['r','i']: for comp in ['r','i']:
dat1DList.append( corr * locrecData[rxType3D+comp][locrecData['freq']== freq].data ) dat1DList.append( corr * locrecData[rxType3D+comp][locrecData['freq']== freq].data )
# Make the survey # Make the survey
sur1D = NSEM.Survey(src1DList) sur1D = MT.Survey(src1DList)
# Make the data # Make the data
dataVec = np.hstack(dat1DList) dataVec = np.hstack(dat1DList)
dat1D = NSEM.Data(sur1D,dataVec) dat1D = MT.Data(sur1D,dataVec)
sur1D.dobs = dataVec sur1D.dobs = dataVec
# Need to take NSEMdata.survey.std and split it as well. # Need to take MTdata.survey.std and split it as well.
std=0.05 std=0.05
sur1D.std = np.abs(sur1D.dobs*std) #+ 0.01*np.linalg.norm(sur1D.dobs) sur1D.std = np.abs(sur1D.dobs*std) #+ 0.01*np.linalg.norm(sur1D.dobs)
mtData1DList.append(dat1D) mtData1DList.append(dat1D)
@@ -266,29 +216,29 @@ def convert3Dto1Dobject(NSEMdata,rxType3D='zyx'):
# Return the the list of data. # Return the the list of data.
return mtData1DList return mtData1DList
def resampleNSEMdataAtFreq(NSEMdata,freqs): def resampleMTdataAtFreq(MTdata,freqs):
""" """
Function to resample NSEMdata at set of frequencies Function to resample MTdata at set of frequencies
""" """
from SimPEG import NSEM from SimPEG import MT
# Make a rec array # Make a rec array
NSEMrec = NSEMdata.toRecArray().data MTrec = MTdata.toRecArray().data
# Find unique locations # Find unique locations
uniLoc = np.unique(NSEMrec[['x','y','z']]) uniLoc = np.unique(MTrec[['x','y','z']])
uniFreq = NSEMdata.survey.freqs uniFreq = MTdata.survey.freqs
# Get the comps # Get the comps
dNames = NSEMrec.dtype dNames = MTrec.dtype
# Loop over all the locations and interpolate # Loop over all the locations and interpolate
for loc in uniLoc: for loc in uniLoc:
# Find the index of the station # Find the index of the station
ind = np.sqrt(np.sum((rec2ndarr(NSEMrec[['x','y','z']]) - rec2ndarr(loc))**2,axis=1)) < 1. # Find dist of 1 m accuracy ind = np.sqrt(np.sum((rec2ndarr(MTrec[['x','y','z']]) - rec2ndarr(loc))**2,axis=1)) < 1. # Find dist of 1 m accuracy
# Make a temporary recArray and interpolate all the components # Make a temporary recArray and interpolate all the components
tArrRec = np.concatenate((simpeg.mkvc(freqs,2),np.ones((len(freqs),1))*rec2ndarr(loc),np.nan*np.ones((len(freqs),12))),axis=1).view(dNames) tArrRec = np.concatenate((simpeg.mkvc(freqs,2),np.ones((len(freqs),1))*rec2ndarr(loc),np.nan*np.ones((len(freqs),12))),axis=1).view(dNames)
for comp in ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi','tzxr','tzxi','tzyr','tzyi']: for comp in ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi','tzxr','tzxi','tzyr','tzyi']:
int1d = sciint.interp1d(NSEMrec[ind]['freq'],NSEMrec[ind][comp],bounds_error=False) int1d = sciint.interp1d(MTrec[ind]['freq'],MTrec[ind][comp],bounds_error=False)
tArrRec[comp] = simpeg.mkvc(int1d(freqs),2) tArrRec[comp] = simpeg.mkvc(int1d(freqs),2)
# Join together # Join together
@@ -297,5 +247,5 @@ def resampleNSEMdataAtFreq(NSEMdata,freqs):
except NameError as e: except NameError as e:
outRecArr = tArrRec outRecArr = tArrRec
# Make the NSEMdata and return # Make the MTdata and return
return NSEM.Data.fromRecArray(outRecArr) return MT.Data.fromRecArray(outRecArr)

Some files were not shown because too many files have changed in this diff Show More