Compare commits

...
41 Commits
Author SHA1 Message Date
Lindsey Heagy 39ddec8702 Merge pull request #339 from simpeg/em/secondary_Rx
Implementation for Inverting Secondary B field
2016-06-20 12:45:00 -06:00
seogi_macbook 2fb0f3fbbb Implementation for Inverting Secondary B field 2016-06-17 07:50:13 -07:00
Lindsey 382b31bd12 Merge pull request #310 from simpeg/ref/regularization
modularizing regularization
2016-05-31 14:09:54 -07:00
Lindsey 6cc509020a Merge pull request #323 from simpeg/feat/plotImage-curvilinear
plotImage for curvilinear mesh
2016-05-30 08:27:56 -07:00
Lindsey Heagy f2e13182bf Merge branch 'dev' into feat/plotImage-curvilinear
# Conflicts:
#	SimPEG/Examples/__init__.py
2016-05-29 16:43:40 -07:00
D Fournier 09cd9c7fa3 Merge branch 'dev' into ref/regularization 2016-05-29 16:26:58 -07:00
Lindsey Heagy 62eb4541cb update example name --> based on mesh 2016-05-29 15:48:15 -07:00
Lindsey 09eb2106ec Merge pull request #307 from simpeg/ref/dev
Ref/dev
2016-05-29 14:50:43 -07:00
D Fournier f8b86abd5a Merge branch 'ref/dev' into ref/regularization 2016-05-29 14:10:46 -07:00
D Fournier e476bf0059 Cleanup Sparse Reg and Directives 2016-05-29 14:09:29 -07:00
Rowan Cockett 825511e9d3 Add a curvilinear plotImage function, update example. 2016-05-29 13:17:22 -07:00
D Fournier 3b4bec9c0b Refactor IRLS iterations, full solves from l2->lp
Adapt Example
2016-05-28 11:27:09 -07:00
D Fournier 022e1f7660 Update IRLS directive to allow multiple GN iterations.
Remove modifications to the ProjGN solver.
Update IRLS example.
2016-05-27 13:11:31 -07:00
D Fournier 406703f1c6 Merge branch 'dev' into ref/dev
Conflicts:
	docs/examples/DC_Forward_PseudoSection.rst
2016-05-27 11:10:39 -07:00
D Fournier 7b72d3a92d Merge branch 'dev' into ref/dev
Conflicts:
	SimPEG/DCIP/DCIPUtils.py
2016-05-27 10:01:28 -07:00
Lindsey cf89f5f6a2 Merge pull request #322 from simpeg/bug/propmap
Bug/propmap
2016-05-26 20:52:42 -07:00
Lindsey Heagy aa1086eba3 use fixed prop map in EM 2016-05-26 18:03:09 -07:00
Lindsey Heagy 1c53129da6 fix bug in prop map linked derivs 2016-05-26 17:58:30 -07:00
sgkang 6fd3be77de Merge pull request #304 from simpeg/dcip/dev
Dcip/dev
2016-05-26 13:27:44 -07:00
D Fournier fd3bde787f Propose change to the Projected_GNCG solver. Add inner GN iterations. Nice improvement to the convergence of IRLS 2016-05-12 14:58:16 -07:00
D Fournier 3cc46131a3 Temporary change ... comment out W and Wsmooth 2016-05-12 08:31:01 -07:00
D Fournier cd2360b815 Stash the regularization between each beta 2016-05-11 23:04:14 -07:00
D Fournier e10d6878fb Remove Wsmooth from def W and replace by parts 2016-05-11 07:58:06 -07:00
Lindsey Heagy 3dd9ecc9cd fix tikhonov 2Deriv 2016-05-10 22:10:19 -07:00
Lindsey Heagy 90a3030796 fixed 2 deriv 2016-05-10 21:39:15 -07:00
D Fournier 7964ebce50 Update directive to None the Wsmooth after iteration. 2016-05-10 17:20:46 -07:00
Lindsey Heagy 955bd54019 notation cleanup in Regularization 2016-05-10 16:46:11 -07:00
Lindsey Heagy 2a802c1aa3 weights --> cell_weights, removed vol term from simple regularization 2016-05-10 16:39:47 -07:00
Lindsey Heagy 3f0c89f10b remove extra Ws 2016-05-10 14:53:43 -07:00
Lindsey Heagy eaa37f42e4 remove duplicate evalSmall 2016-05-10 14:51:56 -07:00
D Fournier fb5434695f Alpha_s default to 1.0 2016-05-10 14:31:45 -07:00
D Fournier e037597ecd Merge branch 'feat/sparse-regularization' into ref/regularization 2016-05-10 13:37:16 -07:00
D Fournier b4ab60c260 Add model mapping to sparse regularization 2016-05-05 11:55:56 -07:00
Lindsey Heagy fbb8cf2731 modularizing regularization 2016-05-04 23:17:01 -07:00
Lindsey Heagy 0379df2bf2 attempt to clean up docs in DCIP utils 2016-05-04 22:27:02 -07:00
Lindsey Heagy 66440b0478 add depreciation warnings to DCIP utils for activeind from topo 2016-05-04 22:14:41 -07:00
Lindsey Heagy dbdcc3cefb use sigma in MfRhoDeriv - due to propmap bug 2016-05-04 22:06:32 -07:00
Lindsey Heagy dd45a6a085 name updates in DC_Forward_PseudoSection, DC_Utils, example for Utils_surface2ind_topo 2016-05-02 11:40:02 -07:00
Lindsey Heagy ba8f270b3a start of surface2ind_topo 2016-05-01 13:17:16 -07:00
Lindsey Heagy 4257ea77b3 remove InjectActiveCellsTopo. you should use InjectActiveCells 2016-04-29 15:09:04 -07:00
Lindsey Heagy a0174e4f30 kwarg name updates 2016-04-29 12:52:45 -07:00
22 changed files with 1079 additions and 760 deletions
+157 -196
View File
@@ -1,12 +1,16 @@
from SimPEG import np from SimPEG import np, Utils
import BaseDC as DC import BaseDC as DC
import BaseDC as IP import BaseDC as IP
import warnings
def getActiveindfromTopo(mesh, topo): def getActiveindfromTopo(mesh, topo):
# def genActiveindfromTopo(mesh, topo): # def genActiveindfromTopo(mesh, topo):
""" """
Get active indices from topography Get active indices from topography
""" """
warnings.warn(
"`getActiveindfromTopo` is deprecated and will be removed in future versions. Use `SimPEG.Utils.surface2ind_topo` instead",
FutureWarning)
from scipy.interpolate import NearestNDInterpolator from scipy.interpolate import NearestNDInterpolator
if mesh.dim==3: if mesh.dim==3:
nCxy = mesh.nCx*mesh.nCy nCxy = mesh.nCx*mesh.nCy
@@ -28,6 +32,9 @@ def gettopoCC(mesh, airind):
""" """
Get topography from active indices of mesh. Get topography from active indices of mesh.
""" """
warnings.warn(
"`gettopoCC` is deprecated and will be removed in future versions. Use `SimPEG.Utils.surface2ind_topo` instead",
FutureWarning)
mesh2D = Mesh.TensorMesh([mesh.hx, mesh.hy], mesh.x0[:2]) mesh2D = Mesh.TensorMesh([mesh.hx, mesh.hy], mesh.x0[:2])
zc = mesh.gridCC[:,2] zc = mesh.gridCC[:,2]
AIRIND = airind.reshape((mesh.vnC[0]*mesh.vnC[1],mesh.vnC[2]), order='F') AIRIND = airind.reshape((mesh.vnC[0]*mesh.vnC[1],mesh.vnC[2]), order='F')
@@ -118,34 +125,27 @@ def readUBC_DC3Dobstopo(filename,mesh,topo,probType="CC"):
def readUBC_DC2DModel(fileName): def readUBC_DC2DModel(fileName):
""" """
Read UBC GIF 2DTensor model and generate 2D Tensor model in simpeg Read UBC GIF 2DTensor model and generate 2D Tensor model in simpeg
Input: :param string fileName: path to the UBC GIF 2D model file
:param fileName, path to the UBC GIF 2D model file :rtype: TensorMesh
:return: SimPEG TensorMesh 2D object
Output:
:param SimPEG TensorMesh 2D object
:return
Created on Thu Nov 12 13:14:10 2015
@author: dominiquef
""" """
from SimPEG import np, mkvc from SimPEG import np, mkvc
# Open fileand skip header... assume that we know the mesh already # Open fileand skip header... assume that we know the mesh already
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') obsfile = np.genfromtxt(fileName, delimiter=' \n', dtype=np.str, comments='!')
dim = np.array(obsfile[0].split(),dtype=float) dim = np.array(obsfile[0].split(), dtype=float)
temp = np.array(obsfile[1].split(),dtype=float) temp = np.array(obsfile[1].split(), dtype=float)
if len(temp) > 1: if len(temp) > 1:
model = np.zeros(dim) model = np.zeros(dim)
for ii in range(len(obsfile)-1): for ii in range(len(obsfile)-1):
mm = np.array(obsfile[ii+1].split(),dtype=float) mm = np.array(obsfile[ii+1].split(), dtype=float)
model[:,ii] = mm model[:,ii] = mm
model = model[:,::-1] model = model[:,::-1]
@@ -153,10 +153,10 @@ def readUBC_DC2DModel(fileName):
else: else:
if len(obsfile[1:])==1: if len(obsfile[1:])==1:
mm = np.array(obsfile[1:].split(),dtype=float) mm = np.array(obsfile[1:].split(), dtype=float)
else: else:
mm = np.array(obsfile[1:],dtype=float) mm = np.array(obsfile[1:], dtype=float)
# Permute the second dimension to flip the order # Permute the second dimension to flip the order
model = mm.reshape(dim[1],dim[0]) model = mm.reshape(dim[1],dim[0])
@@ -169,23 +169,19 @@ def readUBC_DC2DModel(fileName):
return model return model
def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cblabel=True, axlabel = True, colorbar = True, contour = None):
def plot_pseudoSection(DCsurvey, axs, surveyType='dipole-dipole', unitType='volt', clim=None, cblabel=True, axlabel = True, colorbar = True, contour = None):
""" """
Read list of 2D tx-rx location and plot a speudo-section of apparent Read list of 2D tx-rx location and plot a speudo-section of apparent
resistivity. resistivity.
Assumes flat topo for now... Assumes flat topo for now...
Input: :param SurveyDC DCsurvey:
:param d2D, z0 :param string surveyType: Either 'pole-dipole' | 'dipole-dipole'
:switch stype -> Either 'pdp' (pole-dipole) | 'dpdp' (dipole-dipole) :param string unitType: Either 'appResistivity' | 'appConductivity' | 'volt'
:switch dtype=-> Either 'appr' (app. res) | 'appc' (app. con) | 'volt' (potential) :rtype: matplotlib.plt
Output: :return: figure scatter plot overlayed on image
:figure scatter plot overlayed on image
Edited Feb 17th, 2016
@author: dominiquef
""" """
from SimPEG import np from SimPEG import np
@@ -218,39 +214,39 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cbl
Cmid = (Tx[0][0] + Tx[1][0])/2 Cmid = (Tx[0][0] + Tx[1][0])/2
Pmid = (Rx[0][:,0] + Rx[1][:,0])/2 Pmid = (Rx[0][:,0] + Rx[1][:,0])/2
# Change output for dtype # Change output for unitType
if dtype == 'volt': if unitType == 'volt':
rho = np.hstack([rho,data]) rho = np.hstack([rho,data])
else: else:
# Compute pant leg of apparent rho # Compute pant leg of apparent rho
if stype == 'pdp': if surveyType == 'pole-dipole':
leg = data * 2*np.pi * MA * ( MA + MN ) / MN leg = data * 2*np.pi * MA * ( MA + MN ) / MN
elif stype == 'dpdp': 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 """dtype must be 'pdp'(pole-dipole) | 'dpdp' (dipole-dipole) """ print """unitType must be 'pole-dipole' | 'dipole-dipole' """
break break
if dtype == 'appc': if unitType == 'appConductivity':
leg = np.log10(abs(1./leg)) leg = np.log10(abs(1./leg))
rho = np.hstack([rho,leg]) rho = np.hstack([rho,leg])
elif dtype == 'appr': elif unitType == 'appResistivity':
leg = np.log10(abs(leg)) leg = np.log10(abs(leg))
rho = np.hstack([rho,leg]) rho = np.hstack([rho,leg])
else: else:
print """dtype must be 'appr' | 'appc' | 'volt' """ print """unitType must be 'appResistivity' | 'appConductivity' | 'volt' """
break break
midx = np.hstack([midx, ( Cmid + Pmid )/2 ]) midx = np.hstack([midx, ( Cmid + Pmid )/2 ])
@@ -259,7 +255,7 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cbl
# 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)]
grid_rho = griddata(np.c_[midx,midz], rho.T, (grid_x, grid_z), method='linear') grid_rho = griddata(np.c_[midx,midz], rho.T, (grid_x, grid_z), method='linear')
# Scale the color scheme # Scale the color scheme
if clim == None: if clim == None:
vmin, vmax = rho.min(), rho.max() vmin, vmax = rho.min(), rho.max()
@@ -268,36 +264,37 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cbl
# Plot data # Plot data
grid_rho = np.ma.masked_where(np.isnan(grid_rho), grid_rho) grid_rho = np.ma.masked_where(np.isnan(grid_rho), grid_rho)
ph = plt.pcolormesh(grid_x[:,0],grid_z[0,:],grid_rho.T, vmin = vmin, vmax = vmax) ph = plt.pcolormesh(grid_x[:,0],grid_z[0,:],grid_rho.T, vmin = vmin, vmax = vmax)
plt.gca().tick_params(axis='both', which='major', labelsize=8) plt.gca().tick_params(axis='both', which='major', labelsize=8)
if contour is not None: if contour is not None:
plt.contour(grid_x,grid_z,grid_rho,levels = contour,colors = 'r', vmin = vmin, vmax = vmax) plt.contour(grid_x,grid_z,grid_rho,levels = contour,colors = 'r', vmin = vmin, vmax = vmax)
# Add scatter points # Add scatter points
axs.scatter(midx,midz,s=10,c=rho.T, vmin = vmin, vmax = vmax) axs.scatter(midx,midz,s=10,c=rho.T, vmin = vmin, vmax = vmax)
if colorbar: if colorbar:
if dtype == 'volt': if unitType == 'volt':
cbar = plt.colorbar(ph, ax = axs, format="%4.1f",fraction=0.04,orientation="horizontal") cbar = plt.colorbar(ph, ax = axs, format="%4.1f",fraction=0.04,orientation="horizontal")
else: else:
cbar = plt.colorbar(ph, ax = axs, format="$10^{%.1f}$",fraction=0.04,orientation="horizontal") cbar = plt.colorbar(ph, ax = axs, format="$10^{%.1f}$",fraction=0.04,orientation="horizontal")
cmin,cmax = cbar.get_clim()
ticks = np.linspace(cmin,cmax,3)
cbar.set_ticks(ticks)
cbar.ax.tick_params(labelsize=10)
if cblabel:
if dtype == 'appc':
cbar.set_label("App.Cond",size=12)
elif dtype == 'appr':
cbar.set_label("App.Res.",size=12)
elif dtype == 'volt':
cbar.set_label("Potential (V)",size=12)
cmin,cmax = cbar.get_clim()
ticks = np.linspace(cmin,cmax,3)
cbar.set_ticks(ticks)
cbar.ax.tick_params(labelsize=10)
if unitType == 'appConductivity':
cbar.set_label("App.Cond",size=12)
elif unitType == 'appResistivity':
cbar.set_label("App.Res.",size=12)
elif unitType == 'volt':
cbar.set_label("Potential (V)",size=12)
if not axlabel: if not axlabel:
@@ -310,27 +307,24 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cbl
return ph return ph
def gen_DCIPsurvey(endl, mesh, stype, a, b, n): def gen_DCIPsurvey(endl, mesh, surveyType, AM_sep, MN_sep, nrx):
""" """
Load in endpoints and survey specifications to generate Tx, Rx location Load in endpoints and survey specifications to generate Tx, Rx location
stations. stations.
Assumes flat topo for now... Assumes flat topo for now...
Input: :param numpy.array endl: input endpoints [[x1, y1] , [x2, y2]]
:param endl -> input endpoints [x1, y1, z1, x2, y2, z2] :param Mesh mesh: SimPEG mesh object
:object mesh -> SimPEG mesh object :param string surveyType: 'dipole-dipole' | 'pole-dipole' | 'gradient'
:switch stype -> "dpdp" (dipole-dipole) | "pdp" (pole-dipole) | 'gradient' :param float AM_sep: transmitter (A) - receiver (M) seperation
: param a, n -> pole seperation, number of rx dipoles per tx :param float b: receiver dipole seperation
:param float nrx: pole seperation, number of rx dipoles per tx
Output: :rtype: DC.Survey, Src, Rx
:param Tx, Rx -> List objects for each tx location :returns: DC survey, Source
Lines: P1x, P1y, P1z, P2x, P2y, P2z
Created on Wed December 9th, 2015 !! Require clean up to deal with DCsurvey
@author: dominiquef
!! Require clean up to deal with DCsurvey
""" """
from SimPEG import np from SimPEG import np
@@ -346,17 +340,17 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
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 / 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*a stn_x = endl[0,0] + np.array(range(int(nstn)))*dl_x*AM_sep
stn_y = endl[0,1] + np.array(range(int(nstn)))*dl_y*a stn_y = endl[0,1] + np.array(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]]
# Create line of P2 locations # Create line of P2 locations
N = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]] N = np.c_[stn_x+AM_sep*dl_x, stn_y+AM_sep*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
## Build list of Tx-Rx locations depending on survey type ## Build list of Tx-Rx locations depending on survey type
# Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn] # Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn]
@@ -366,14 +360,14 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
SrcList = [] SrcList = []
if stype != 'gradient': if surveyType != 'gradient':
for ii in range(0, int(nstn)-1): for ii in range(0, int(nstn)-1):
if stype == 'dpdp': if surveyType == 'dipole-dipole':
tx = np.c_[M[ii,:],N[ii,:]] tx = np.c_[M[ii,:],N[ii,:]]
elif stype == 'pdp': elif surveyType == 'pole-dipole':
tx = np.c_[M[ii,:],M[ii,:]] tx = np.c_[M[ii,:],M[ii,:]]
# Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]]) # Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]])
@@ -382,33 +376,33 @@ 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([np.floor( (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*b + np.array(range(int(nstn)))*dl_x*a stn_x = N[ii,0] + dl_x*MN_sep + np.array(range(int(nstn)))*dl_x*AM_sep
stn_y = N[ii,1] + dl_y*b + np.array(range(int(nstn)))*dl_y*a stn_y = N[ii,1] + dl_y*MN_sep + np.array(range(int(nstn)))*dl_y*AM_sep
# Create receiver poles # Create receiver poles
# Create line of P1 locations # Create line of P1 locations
P1 = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]] P1 = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]]
# Create line of P2 locations # Create line of P2 locations
P2 = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]] P2 = np.c_[stn_x+AM_sep*dl_x, stn_y+AM_sep*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
Rx.append(np.c_[P1,P2]) Rx.append(np.c_[P1,P2])
rxClass = DC.RxDipole(P1, P2) rxClass = DC.RxDipole(P1, P2)
Tx.append(tx) Tx.append(tx)
if stype == 'dpdp': if surveyType == 'dipole-dipole':
srcClass = DC.SrcDipole([rxClass], M[ii,:],N[ii,:]) srcClass = DC.SrcDipole([rxClass], M[ii,:],N[ii,:])
elif stype == 'pdp': elif surveyType == 'pole-dipole':
srcClass = DC.SrcDipole([rxClass], M[ii,:],M[ii,:]) srcClass = DC.SrcDipole([rxClass], M[ii,:],M[ii,:])
SrcList.append(srcClass) SrcList.append(srcClass)
elif stype == 'gradient': elif surveyType == 'gradient':
# Gradient survey only requires Tx at end of line and creates a square # Gradient survey only requires Tx at end of line and creates a square
# grid of receivers at in the middle at a pre-set minimum distance # grid of receivers at in the middle at a pre-set minimum distance
@@ -416,23 +410,23 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
Tx.append(np.c_[M[0,:],N[-1,:]]) Tx.append(np.c_[M[0,:],N[-1,:]])
# Get the edge limit of survey area # Get the edge limit of survey area
min_x = endl[0,0] + dl_x * b min_x = endl[0,0] + dl_x * MN_sep
min_y = endl[0,1] + dl_y * b min_y = endl[0,1] + dl_y * MN_sep
max_x = endl[1,0] - dl_x * b max_x = endl[1,0] - dl_x * MN_sep
max_y = endl[1,1] - dl_y * b max_y = endl[1,1] - dl_y * MN_sep
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 / 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*a stn_x = min_x + np.array(range(int(nstn)))*dl_x*AM_sep
stn_y = min_y + np.array(range(int(nstn)))*dl_y*a stn_y = min_y + np.array(range(int(nstn)))*dl_y*AM_sep
# Define number of cross lines # Define number of cross lines
nlin = int(np.floor( box_w / a )) nlin = int(np.floor( box_w / AM_sep ))
lind = range(-nlin,nlin+1) lind = range(-nlin,nlin+1)
ngrad = nstn * len(lind) ngrad = nstn * len(lind)
@@ -441,12 +435,12 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
for ii in range( len(lind) ): for ii in range( len(lind) ):
# Move line in perpendicular direction by dipole spacing # Move line in perpendicular direction by dipole spacing
lxx = stn_x - lind[ii]*a*dl_y lxx = stn_x - lind[ii]*AM_sep*dl_y
lyy = stn_y + lind[ii]*a*dl_x lyy = stn_y + lind[ii]*AM_sep*dl_x
M = np.c_[ lxx, lyy , np.ones(nstn).T*mesh.vectorNz[-1]] M = np.c_[ lxx, lyy , np.ones(nstn).T*mesh.vectorNz[-1]]
N = np.c_[ lxx+a*dl_x, lyy+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]] N = np.c_[ lxx+AM_sep*dl_x, lyy+AM_sep*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
rx[(ii*nstn):((ii+1)*nstn),:] = np.c_[M,N] rx[(ii*nstn):((ii+1)*nstn),:] = np.c_[M,N]
@@ -455,44 +449,38 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
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 """stype must be either 'pdp', 'dpdp' 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
def writeUBC_DCobs(fileName, DCsurvey, dtype='3D', stype='SURFACE', iptype = 0):
def writeUBC_DCobs(fileName, DCsurvey, dim, surveyType, iptype = 0):
""" """
Write UBC GIF DCIP 2D or 3D observation file Write UBC GIF DCIP 2D or 3D observation file
Input: :param string fileName: including path where the file is written out
:string fileName -> including path where the file is written out :param Survey DCsurvey: DC survey class object
:DCsurvey DC survey class object :param string dim: either '2D' | '3D'
:string dtype -> either '2D' | '3D' :param string surveyType: either 'SURFACE' | 'GENERAL'
:string stype -> either 'SURFACE' | 'GENERAL' :rtype: file
:return: UBC2D-Data file
Output:
:param UBC2D-Data file
:return
Last edit: February 16th, 2016
@author: dominiquef
""" """
from SimPEG import mkvc from SimPEG import mkvc
assert (dtype=='2D') | (dtype=='3D'), "Data must be either '2D' | '3D'" assert (dim=='2D') | (dim=='3D'), "Data must be either '2D' | '3D'"
assert (stype=='SURFACE') | (stype=='GENERAL') | (stype=='SIMPLE'), "Data must be either 'SURFACE' | 'GENERAL' | 'SIMPLE'" assert (surveyType=='SURFACE') | (surveyType=='GENERAL') | (surveyType=='SIMPLE'), "Data must be either 'SURFACE' | 'GENERAL' | 'SIMPLE'"
fid = open(fileName,'w') fid = open(fileName,'w')
fid.write('! ' + surveyType + ' FORMAT\n')
if iptype!=0: if iptype!=0:
fid.write('IPTYPE=%i\n'%iptype) fid.write('IPTYPE=%i\n'%iptype)
else: else:
fid.write('! ' + stype + ' FORMAT\n') fid.write('! ' + stype + ' FORMAT\n')
count = 0 count = 0
for ii in range(DCsurvey.nSrc): for ii in range(DCsurvey.nSrc):
@@ -506,33 +494,33 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype='3D', stype='SURFACE', iptype = 0):
M = rx[0] M = rx[0]
N = rx[1] N = rx[1]
# Adapt source-receiver location for dtype and stype # Adapt source-receiver location for dim and surveyType
if dtype=='2D': if dim=='2D':
if stype == 'SIMPLE': if surveyType == 'SIMPLE':
#fid.writelines("%e " % ii for ii in mkvc(tx[0,:])) #fid.writelines("%e " % ii for ii in mkvc(tx[0,:]))
A = np.repeat(tx[0,0],M.shape[0],axis=0) A = np.repeat(tx[0,0],M.shape[0],axis=0)
B = np.repeat(tx[0,1],M.shape[0],axis=0) B = np.repeat(tx[0,1],M.shape[0],axis=0)
M = M[:,0] M = M[:,0]
N = N[:,0] N = N[:,0]
np.savetxt(fid, np.c_[A, B, M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%e',delimiter=' ',newline='\n') np.savetxt(fid, np.c_[A, B, M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%e',delimiter=' ',newline='\n')
else: else:
if stype == 'SURFACE': if surveyType == 'SURFACE':
fid.writelines("%f " % ii for ii in mkvc(tx[0,:])) fid.writelines("%f " % ii for ii in mkvc(tx[0,:]))
M = M[:,0] M = M[:,0]
N = N[:,0] N = N[:,0]
if stype == 'GENERAL': if surveyType == 'GENERAL':
# Flip sign for z-elevation to depth # Flip sign for z-elevation to depth
tx[2::2,:] = -tx[2::2,:] tx[2::2,:] = -tx[2::2,:]
fid.writelines("%e " % ii for ii in mkvc(tx[::2,:])) fid.writelines("%e " % ii for ii in mkvc(tx[::2,:]))
M = M[:,0::2] M = M[:,0::2]
N = N[:,0::2] N = N[:,0::2]
@@ -540,31 +528,31 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype='3D', stype='SURFACE', iptype = 0):
# Flip sign for z-elevation to depth # Flip sign for z-elevation to depth
M[:,1::2] = -M[:,1::2] M[:,1::2] = -M[:,1::2]
N[:,1::2] = -N[:,1::2] N[:,1::2] = -N[:,1::2]
fid.write('%i\n'% nD) fid.write('%i\n'% nD)
np.savetxt(fid, np.c_[ M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%f',delimiter=' ',newline='\n') np.savetxt(fid, np.c_[ M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%f',delimiter=' ',newline='\n')
if dtype=='3D': if dim=='3D':
if stype == 'SURFACE': if surveyType == 'SURFACE':
fid.writelines("%e " % ii for ii in mkvc(tx[0:2,:])) fid.writelines("%e " % ii for ii in mkvc(tx[0:2,:]))
M = M[:,0:2] M = M[:,0:2]
N = N[:,0:2] N = N[:,0:2]
if stype == 'GENERAL': if surveyType == 'GENERAL':
fid.writelines("%e " % ii for ii in mkvc(tx[0:3,:])) fid.writelines("%e " % ii for ii in mkvc(tx[0:3,:]))
fid.write('%i\n'% nD) fid.write('%i\n'% nD)
np.savetxt(fid, np.c_[ M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%e',delimiter=' ',newline='\n') np.savetxt(fid, np.c_[ M, N , DCsurvey.dobs[count:count+nD], DCsurvey.std[count:count+nD] ], fmt='%e',delimiter=' ',newline='\n')
fid.write('\n') fid.write('\n')
count += nD count += nD
fid.close() fid.close()
def convertObs_DC3D_to_2D(DCsurvey,lineID, flag = 'local'): def convertObs_DC3D_to_2D(DCsurvey, lineID, flag='local'):
""" """
Read DC survey and projects the coordinate system Read DC survey and projects the coordinate system
according to the flag = 'Xloc' | 'Yloc' | 'local' (default) according to the flag = 'Xloc' | 'Yloc' | 'local' (default)
@@ -573,15 +561,9 @@ def convertObs_DC3D_to_2D(DCsurvey,lineID, flag = 'local'):
The Z value is preserved, but Y coordinates zeroed. The Z value is preserved, but Y coordinates zeroed.
Input: :param DC.Survey survey3D: 3D simpeg DC survey
:param survey3D :rtype: DC.Survey
:return: survey2D
Output:
:figure survey2D
Edited April 6th, 2016
@author: dominiquef
""" """
from SimPEG import np from SimPEG import np
@@ -666,39 +648,34 @@ def convertObs_DC3D_to_2D(DCsurvey,lineID, flag = 'local'):
DCsurvey2D.std = np.asarray(DCsurvey.std) DCsurvey2D.std = np.asarray(DCsurvey.std)
return DCsurvey2D return DCsurvey2D
def readUBC_DC3Dobs(fileName, dtype = 'DC'): def readUBC_DC3Dobs(fileName, rtype = 'DC'):
""" """
Read UBC GIF IP 3D observation file and generate survey Read UBC GIF IP 3D observation file and generate survey
Input: :param string fileName:, path to the UBC GIF 3D obs file
:param fileName, path to the UBC GIF 3D obs file :rtype: Survey
:return: DCIPsurvey
Output:
:param IPsurvey
:return
@author: dominiquef
""" """
zflag = True # Flag for z value provided zflag = True # Flag for z value provided
# Load file # Load file
if dtype == 'IP': if rtype == 'IP':
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='IPTYPE') obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='IPTYPE')
elif dtype == 'DC': elif 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 "dtype must be 'DC'(default) | 'IP'" print "rtype must be 'DC'(default) | 'IP'"
# Pre-allocate # Pre-allocate
srcLists = [] srcLists = []
Rx = [] Rx = []
d = [] d = []
wd = [] wd = []
# Countdown for number of obs/tx # Countdown for number of obs/tx
count = 0 count = 0
@@ -717,7 +694,7 @@ def readUBC_DC3Dobs(fileName, dtype = 'DC'):
# Check if z value is provided, if False -> nan # Check if z value is provided, if False -> nan
if len(temp)==5: if len(temp)==5:
tx = np.r_[temp[0:2],np.nan,temp[2:4],np.nan] tx = np.r_[temp[0:2],np.nan,temp[2:4],np.nan]
zflag = False # Pass on the flag to the receiver loc zflag = False # Pass on the flag to the receiver loc
else: else:
@@ -729,12 +706,12 @@ def readUBC_DC3Dobs(fileName, dtype = 'DC'):
temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') # Get the string temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') # Get the string
# Filter out negative IP # Filter out negative IP
# if temp[-2] < 0: # if temp[-2] < 0:
# count = count -1 # count = count -1
# print "Negative!" # print "Negative!"
# #
# else: # else:
# If the Z-location is provided, otherwise put nan # If the Z-location is provided, otherwise put nan
if zflag: if zflag:
@@ -772,17 +749,9 @@ def readUBC_DC2Dobs(fileName):
------- NEEDS TO BE UPDATED ------ ------- NEEDS TO BE UPDATED ------
Read UBC GIF 2D observation file and generate arrays for tx-rx location Read UBC GIF 2D observation file and generate arrays for tx-rx location
Input: :param string fileName: path to the UBC GIF 2D model file
:param fileName, path to the UBC GIF 2D model file :rtype: (DC.Src, DC.Rx, ??, ??)
:return: source_locs, rx_locs, ??, ??
Output:
:param rx, tx
:return
Created on Thu Nov 12 13:14:10 2015
@author: dominiquef
""" """
from SimPEG import np from SimPEG import np
@@ -822,11 +791,9 @@ def readUBC_DC2Dpre(fileName):
Read UBC GIF DCIP 2D observation file and generate arrays for tx-rx location Read UBC GIF DCIP 2D observation file and generate arrays for tx-rx location
Input: Input:
:param fileName, path to the UBC GIF 3D obs file :param string fileName: path to the UBC GIF 3D obs file
:rtype: DC.Survey
Output: :return: DCsurvey
DCsurvey
:return
Created on Mon March 9th, 2016 << Doug's 70th Birthday !! >> Created on Mon March 9th, 2016 << Doug's 70th Birthday !! >>
@@ -888,12 +855,9 @@ def readUBC_DC2DMesh(fileName):
""" """
Read UBC GIF 2DTensor mesh and generate 2D Tensor mesh in simpeg Read UBC GIF 2DTensor mesh and generate 2D Tensor mesh in simpeg
Input: :param string fileName: path to the UBC GIF mesh file
:param fileName, path to the UBC GIF mesh file :rtype: Mesh.TensorMesh
:return: SimPEG TensorMesh 2D object
Output:
:param SimPEG TensorMesh 2D object
:return
Created on Thu Nov 12 13:14:10 2015 Created on Thu Nov 12 13:14:10 2015
@@ -959,12 +923,9 @@ def xy_2_lineID(DCsurvey):
they were collected. May need to generalize for random they were collected. May need to generalize for random
point locations, but will be more expensive point locations, but will be more expensive
Input: :param numpy.array DCdict: Vectors of station location
:param DCdict Vectors of station location :rtype: numpy.array
:return: LineID Vector of integers
Output:
:param LineID Vector of integers
:return
Created on Thu Feb 11, 2015 Created on Thu Feb 11, 2015
+115 -54
View File
@@ -144,6 +144,7 @@ class BetaSchedule(InversionDirective):
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
class TargetMisfit(InversionDirective): class TargetMisfit(InversionDirective):
chifact = 1. chifact = 1.
@@ -242,12 +243,6 @@ class SaveOutputDictEveryIteration(_SaveEveryIteration):
# Save the file as a npz # Save the file as a npz
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) 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)
# class UpdateReferenceModel(Parameter):
# mref0 = None
# def nextIter(self):
# mref = getattr(self, 'm_prev', None) # mref = getattr(self, 'm_prev', None)
# if mref is None: # if mref is None:
# if self.debug: print 'UpdateReferenceModel is using mref0' # if self.debug: print 'UpdateReferenceModel is using mref0'
@@ -258,56 +253,138 @@ class SaveOutputDictEveryIteration(_SaveEveryIteration):
class Update_IRLS(InversionDirective): class Update_IRLS(InversionDirective):
eps_min = None eps_min = None
eps_p = None
eps_q = None
norms = [2.,2.,2.,2.]
factor = None factor = None
gamma = None gamma = None
phi_m_last = None phi_m_last = None
phi_d_last = None phi_d_last = None
f_old = None
f_min_change = 1e-2
beta_tol = 5e-2
# Solving parameter for IRLS (mode:2)
IRLSiter = 0
minGNiter = 5
maxIRLSiter = 10
iterStart = 0
# Beta schedule
coolingFactor = 2.
coolingRate = 1
mode = 1
@property
def target(self):
if getattr(self, '_target', None) is None:
self._target = self.survey.nD*0.5
return self._target
@target.setter
def target(self, val):
self._target = val
def initialize(self): def initialize(self):
# Scale the regularization for changes in norm if self.mode == 1:
if getattr(self, 'phi_m_last', None) is not None: self.reg.norms = [2., 2., 2., 2.]
self.reg.curModel = self.invProb.curModel
self.reg.gamma = 1.
phim_new = self.reg.eval(self.invProb.curModel)
self.gamma = self.phi_m_last / phim_new
self.reg.curModel = self.invProb.curModel
self.reg.gamma = self.gamma
if getattr(self, 'phi_d_last', None) is None:
self.phi_d_last = self.invProb.phi_d
def endIter(self): def endIter(self):
# Cool the threshold parameter if required
if getattr(self, 'factor', None) is not None:
eps = self.reg.eps / self.factor
if getattr(self, 'eps_min', None) is not None: # After reaching target misfit with l2-norm, switch to IRLS (mode:2)
self.reg.eps = np.max([self.eps_min,eps]) if self.invProb.phi_d < self.target and self.mode == 1:
print "Convergence with smooth l2-norm regularization: Start IRLS steps..."
self.mode = 2
print self.eps_p, self.eps_q, self.norms
self.reg.eps_p = self.eps_p
self.reg.eps_q = self.eps_q
self.reg.norms = self.norms
self.coolingFactor = 1.
self.coolingRate = 1
self.iterStart = self.opt.iter
self.phi_d_last = self.invProb.phi_d
self.phi_m_last = self.invProb.phi_m_last
self.reg.l2model = self.invProb.curModel
self.reg.curModel = self.invProb.curModel
if getattr(self, 'f_old', None) is None:
self.f_old = self.reg.eval(self.invProb.curModel)#self.invProb.evalFunction(self.invProb.curModel, return_g=False, return_H=False)
# Beta Schedule
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
self.invProb.beta /= self.coolingFactor
# Only update after GN iterations
if (self.opt.iter-self.iterStart) % self.minGNiter == 0 and self.mode==2:
self.IRLSiter += 1
phim_new = self.reg.eval(self.invProb.curModel)
self.f_change = np.abs(self.f_old - phim_new) / self.f_old
print "Regularization decrease: %6.3e" % (self.f_change)
# Check for maximum number of IRLS cycles
if self.IRLSiter == self.maxIRLSiter:
print "Reach maximum number of IRLS cycles: %i" % self.maxIRLSiter
self.opt.stopNextIteration = True
return
# Check if the function has changed enough
if self.f_change < self.f_min_change and self.IRLSiter > 1:
print "Minimum decrease in regularization. End of IRLS"
self.opt.stopNextIteration = True
return
else: else:
self.reg.eps = eps self.f_old = phim_new
# Get phi_m at the end of current iteration # Cool the threshold parameter if required
self.phi_m_last = self.invProb.phi_m_last if getattr(self, 'factor', None) is not None:
eps = self.reg.eps / self.factor
# Update the model used for the IRLS weights if getattr(self, 'eps_min', None) is not None:
self.reg.curModel = self.invProb.curModel self.reg.eps = np.max([self.eps_min,eps])
else:
self.reg.eps = eps
# Temporarely set gamma to 1. to get raw phi_m # Get phi_m at the end of current iteration
self.reg.gamma = 1. self.phi_m_last = self.invProb.phi_m_last
# Compute new model objective function value # Reset the regularization matrices so that it is
phim_new = self.reg.eval(self.invProb.curModel) # recalculated for current model
self.reg._Wsmall = None
self.reg._Wx = None
self.reg._Wy = None
self.reg._Wz = None
# Update gamma to scale the regularization between IRLS iterations # Update the model used for the IRLS weights
self.reg.gamma = self.phi_m_last / phim_new self.reg.curModel = self.invProb.curModel
# Set the weighting matrix to None so that it is recomputed next time # Temporarely set gamma to 1. to get raw phi_m
# it is called in the inversion self.reg.gamma = 1.
self.reg._W = None
# Compute new model objective function value
phim_new = self.reg.eval(self.invProb.curModel)
# Update gamma to scale the regularization between IRLS iterations
self.reg.gamma = self.phi_m_last / phim_new
# Reset the regularization matrices again for new gamma
self.reg._Wsmall = None
self.reg._Wx = None
self.reg._Wy = None
self.reg._Wz = None
# Check if misfit is within the tolerance, otherwise scale beta
val = self.invProb.phi_d / (self.survey.nD*0.5)
if np.abs(1.-val) > self.beta_tol:
self.invProb.beta = self.invProb.beta * self.survey.nD*0.5 / self.invProb.phi_d
class Update_lin_PreCond(InversionDirective): class Update_lin_PreCond(InversionDirective):
""" """
@@ -360,19 +437,3 @@ class Update_Wj(InversionDirective):
JtJdiag = JtJdiag / max(JtJdiag) JtJdiag = JtJdiag / max(JtJdiag)
self.reg.wght = JtJdiag self.reg.wght = JtJdiag
class Scale_Beta(InversionDirective):
"""
Instead of a linear cooling schedule, beta is allowed to change based
on the ratio between the target misfit and the current data misfit. The
update is done only if the misfit is outside some threshold bounds.
"""
tol = 0.05
def endIter(self):
# Check if misfit is within the tolerance, otherwise adjust beta
val = self.invProb.phi_d / (self.survey.nD*0.5)
if np.abs(1.-val) > self.tol:
self.invProb.beta = self.invProb.beta * self.survey.nD*0.5 / self.invProb.phi_d
+3 -8
View File
@@ -169,9 +169,7 @@ class BaseEMProblem(Problem.BaseProblem):
dMeSigmaI_dI = -self.MeSigmaI**2 dMeSigmaI_dI = -self.MeSigmaI**2
dMe_dsig = self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma)(u) dMe_dsig = self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma)(u)
dsig_dm = self.curModel.sigmaDeriv return dMeSigmaI_dI * ( dMe_dsig * self.curModel.sigmaDeriv )
return dMeSigmaI_dI * ( dMe_dsig * ( dsig_dm))
# return self.mesh.getEdgeInnerProductDeriv(self.curModel.sigma, invMat=True)(u)
@property @property
def MfRho(self): def MfRho(self):
@@ -187,8 +185,7 @@ class BaseEMProblem(Problem.BaseProblem):
""" """
Derivative of :code:`MfRho` with respect to the model. Derivative of :code:`MfRho` with respect to the model.
""" """
return self.mesh.getFaceInnerProductDeriv(self.curModel.rho)(u) * (-Utils.sdiag(self.curModel.rho**2) * self.curModel.sigmaDeriv) return self.mesh.getFaceInnerProductDeriv(self.curModel.rho)(u) * self.curModel.rhoDeriv
# self.curModel.rhoDeriv
@property @property
def MfRhoI(self): def MfRhoI(self):
@@ -208,9 +205,7 @@ class BaseEMProblem(Problem.BaseProblem):
dMfRhoI_dI = -self.MfRhoI**2 dMfRhoI_dI = -self.MfRhoI**2
dMf_drho = self.mesh.getFaceInnerProductDeriv(self.curModel.rho)(u) dMf_drho = self.mesh.getFaceInnerProductDeriv(self.curModel.rho)(u)
return dMfRhoI_dI * ( dMf_drho * (-Utils.sdiag(self.curModel.rho**2) * self.curModel.sigmaDeriv) ) return dMfRhoI_dI * ( dMf_drho * self.curModel.rhoDeriv )
# return self.mesh.getFaceInnerProductDeriv(self.curModel.rho, invMat=True)(u) * self.curModel.rhoDeriv
class BaseEMSurvey(Survey.BaseSurvey): class BaseEMSurvey(Survey.BaseSurvey):
+31
View File
@@ -60,6 +60,20 @@ class Fields(SimPEG.Problem.Fields):
return self._bPrimary(solution, srcList) + self._bSecondary(solution, srcList) return self._bPrimary(solution, srcList) + self._bSecondary(solution, srcList)
def _bSecondary(self, solution, srcList):
"""
Total magnetic flux density is sum of primary and secondary
:param numpy.ndarray solution: field we solved for
:param list srcList: list of sources
:rtype: numpy.ndarray
:return: total magnetic flux density
"""
if getattr(self, '_bSecondary', None) is None:
raise NotImplementedError ('Getting b from %s is not implemented' %self.knownFields.keys()[0])
return self._bSecondary(solution, srcList)
def _h(self, solution, srcList): def _h(self, solution, srcList):
""" """
Total magnetic field is sum of primary and secondary Total magnetic field is sum of primary and secondary
@@ -124,6 +138,21 @@ class Fields(SimPEG.Problem.Fields):
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)
return np.array(self._bDeriv_u(src, du_dm_v, adjoint) + self._bDeriv_m(src, v, adjoint), dtype = complex) return np.array(self._bDeriv_u(src, du_dm_v, adjoint) + self._bDeriv_m(src, v, adjoint), dtype = complex)
def _bSecondaryDeriv(self, src, du_dm_v, v, adjoint = False):
"""
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 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 bool adjoint: adjoint?
:rtype: numpy.ndarray
:return: derivative times a vector (or tuple for adjoint)
"""
# TODO: modify when primary field is dependent on m
return self._bDeriv(src, du_dm_v, v, adjoint = adjoint)
def _hDeriv(self, src, du_dm_v, v, adjoint = False): def _hDeriv(self, src, du_dm_v, v, adjoint = False):
""" """
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
@@ -471,6 +500,8 @@ class Fields3D_b(Fields):
return 'E' return 'E'
elif fieldType == 'b': elif fieldType == 'b':
return 'F' return 'F'
elif fieldType == 'bSecondary':
return 'F'
elif (fieldType == 'h') or (fieldType == 'j'): elif (fieldType == 'h') or (fieldType == 'j'):
return'CCV' return'CCV'
else: else:
+13
View File
@@ -97,6 +97,19 @@ class Point_b(BaseRx):
self.projField = 'b' self.projField = 'b'
super(Point_b, self).__init__(locs, orientation, component) super(Point_b, self).__init__(locs, orientation, component)
class Point_bSecondary(BaseRx):
"""
Magnetic flux FDEM receiver
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
:param string orientation: receiver orientation 'x', 'y' or 'z'
:param string component: real or imaginary component 'real' or 'imag'
"""
def __init__(self, locs, orientation=None, component=None):
self.projField = 'bSecondary'
super(Point_bSecondary, self).__init__(locs, orientation, component)
class Point_h(BaseRx): class Point_h(BaseRx):
""" """
+15 -17
View File
@@ -2,7 +2,7 @@ from SimPEG import Mesh, Utils, np, sp
import SimPEG.DCIP as DC import SimPEG.DCIP as DC
import time import time
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', plotIt=True): def run(loc=None, sig=None, radi=None, param=None, surveyType='dipole-dipole', unitType='appConductivity', plotIt=True):
""" """
DC Forward Simulation DC Forward Simulation
===================== =====================
@@ -15,14 +15,14 @@ def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', p
loc = Location of spheres [[x1,y1,z1],[x2,y2,z2]] loc = Location of spheres [[x1,y1,z1],[x2,y2,z2]]
radi = Radius of spheres [r1,r2] radi = Radius of spheres [r1,r2]
param = Conductivity of background and two spheres [m0,m1,m2] param = Conductivity of background and two spheres [m0,m1,m2]
stype = survey type "pdp" (pole dipole) or "dpdp" (dipole dipole) surveyType = survey type 'pole-dipole' or 'dipole-dipole'
dtype = Data type "appr" (app res) | "appc" (app cond) | "volt" (potential) unitType = Data type "appResistivity" | "appConductivity" | "volt"
Created by @fourndo Created by @fourndo
""" """
assert stype in ['pdp', 'dpdp'], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)" assert surveyType in ['pole-dipole', 'dipole-dipole'], "Source type (surveyType) must be pdp or dpdp (pole dipole or dipole dipole)"
assert dtype in ['appr', 'appc', 'volt'], "Data type (dtype) must be appr (app res) or appc (app cond) or volt (potential)" assert unitType in ['appResistivity', 'appConductivity', 'volt'], "Unit type (unitType) must be appResistivity or appConductivity or volt (potential)"
if loc is None: if loc is None:
loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]] loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]]
@@ -73,8 +73,8 @@ def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', p
locs = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*mesh.vectorNz[-1]] locs = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*mesh.vectorNz[-1]]
# We will handle the geometry of the survey for you and create all the combination of tx-rx along line # We will handle the geometry of the survey for you and create all the combination of tx-rx along line
# [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, surveyType, param[0], param[1], param[2])
survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, surveyType, param[0], param[1], param[2])
# Define some global geometry # Define some global geometry
dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) ) dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) )
@@ -118,8 +118,8 @@ def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', p
rxloc_N = np.asarray(Rx[ii][:,3:]) rxloc_N = np.asarray(Rx[ii][:,3:])
# For usual cases "dpdp" or "gradient" # For usual cases 'dipole-dipole' or "gradient"
if stype == 'pdp': if surveyType == 'pole-dipole':
# Create an "inifinity" pole # Create an "inifinity" pole
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
@@ -157,12 +157,12 @@ def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', p
fig = plt.figure(figsize=(7,7)) fig = plt.figure(figsize=(7,7))
ax = plt.subplot(2,1,1, aspect='equal') ax = plt.subplot(2,1,1, aspect='equal')
# Plot the location of the spheres for reference # Plot the location of the spheres for reference
circle1=plt.Circle((loc[0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3) circle1=plt.Circle((loc[0,0], loc[2,0]), radi[0], color='w', fill=False, lw=3)
circle2=plt.Circle((loc[0,1],loc[2,1]),radi[1],color='k',fill=False, lw=3) circle2=plt.Circle((loc[0,1], loc[2,1]), radi[1], color='k', fill=False, lw=3)
ax.add_artist(circle1) ax.add_artist(circle1)
ax.add_artist(circle2) ax.add_artist(circle2)
dat = mesh.plotSlice(np.log10(model), ax =ax, normal = 'Y', dat = mesh.plotSlice(np.log10(model), ax = ax, normal = 'Y',
ind = indy,grid=True, clim = np.log10([sig.min(),sig.max()])) ind = indy,grid=True, clim = np.log10([sig.min(),sig.max()]))
ax.set_title('3-D model') ax.set_title('3-D model')
@@ -188,15 +188,13 @@ def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', dtype='appc', p
ax2 = plt.subplot(2,1,2, aspect='equal') ax2 = plt.subplot(2,1,2, aspect='equal')
# Plot the location of the spheres for reference # Plot the location of the spheres for reference
circle1=plt.Circle((loc[0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3) circle1=plt.Circle((loc[0,0], loc[2,0]), radi[0], color='w', fill=False, lw=3)
circle2=plt.Circle((loc[0,1],loc[2,1]),radi[1],color='k',fill=False, lw=3) circle2=plt.Circle((loc[0,1], loc[2,1]), radi[1], color='k', fill=False, lw=3)
ax2.add_artist(circle1) ax2.add_artist(circle1)
ax2.add_artist(circle2) ax2.add_artist(circle2)
# Add the speudo section # Add the speudo section
dat = DC.plot_pseudoSection(survey2D,ax2,stype=stype, dtype = dtype) dat = DC.plot_pseudoSection(survey2D, ax2, surveyType=surveyType, unitType=unitType) # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
# plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
# plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y') # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y')
# plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k') # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k')
ax2.set_title('Apparent Conductivity data') ax2.set_title('Apparent Conductivity data')
+36 -44
View File
@@ -1,7 +1,7 @@
from SimPEG import * from SimPEG import *
def run(N=200, plotIt=True): def run(N=100, plotIt=True):
""" """
Inversion: Linear Problem Inversion: Linear Problem
========================= =========================
@@ -18,6 +18,8 @@ def run(N=200, plotIt=True):
mesh = Mesh.TensorMesh([N]) mesh = Mesh.TensorMesh([N])
m0 = np.ones(mesh.nC) * 1e-4 m0 = np.ones(mesh.nC) * 1e-4
mref = np.zeros(mesh.nC)
nk = 10 nk = 10
jk = np.linspace(1.,nk,nk) jk = np.linspace(1.,nk,nk)
p = -2. p = -2.
@@ -50,57 +52,47 @@ def run(N=200, plotIt=True):
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 = Regularization.Simple(mesh)
reg.wght = wr # 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=30,lower=-2.,upper=2., maxIterCG= 20, tolCG = 1e-4) # opt = Optimization.ProjectedGNCG(maxIter=20,lower=-2.,upper=2., maxIterCG= 10, tolCG = 1e-4)
invProb = InvProblem.BaseInvProblem(dmis, reg, opt) # invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
invProb.curModel = m0 # invProb.curModel = m0
#
beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1) # beta = Directives.BetaSchedule(coolingFactor=2, coolingRate=1)
target = Directives.TargetMisfit() # target = Directives.TargetMisfit()
#
betaest = Directives.BetaEstimate_ByEig() betaest = Directives.BetaEstimate_ByEig()
inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest, target]) # inv = Inversion.BaseInversion(invProb, directiveList=[beta, betaest, target])
#
#
mrec = inv.run(m0) # mrec = inv.run(m0)
ml2 = mrec # ml2 = mrec
print "Final misfit:" + str(invProb.dmisfit.eval(mrec)) # print "Final misfit:" + str(invProb.dmisfit.eval(mrec))
#
# Switch regularization to sparse # # Switch regularization to sparse
phim = invProb.phi_m_last # phim = invProb.phi_m_last
phid = invProb.phi_d # phid = invProb.phi_d
reg = Regularization.Sparse(mesh) reg = Regularization.Sparse(mesh)
reg.mref = mref
reg.cell_weights = wr
#==============================================================================
# fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
# dmdx = reg.mesh.cellDiffxStencil * mrec
# plt.plot(np.sort(dmdx))
#==============================================================================
#reg.recModel = mrec
reg.wght = np.ones(mesh.nC)
reg.mref = np.zeros(mesh.nC) reg.mref = np.zeros(mesh.nC)
reg.eps_p = 5e-2 eps_p = 5e-2
reg.eps_q = 1e-2 eps_q = 5e-2
reg.norms = [0., 0., 2., 2.] norms = [0., 0., 2., 2.]
reg.wght = wr
opt = Optimization.ProjectedGNCG(maxIter=10 ,lower=-2.,upper=2., maxIterLS = 20, maxIterCG= 20, 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, beta = invProb.beta*2.) invProb = InvProblem.BaseInvProblem(dmis, reg, opt)
beta = Directives.BetaSchedule(coolingFactor=1, coolingRate=1) update_Jacobi = Directives.Update_lin_PreCond()
#betaest = Directives.BetaEstimate_ByEig() IRLS = Directives.Update_IRLS( norms=norms, eps_p=eps_p, eps_q=eps_q)
target = Directives.TargetMisfit()
IRLS =Directives.Update_IRLS( phi_m_last = phim, phi_d_last = phid )
inv = Inversion.BaseInversion(invProb, directiveList=[beta,IRLS]) inv = Inversion.BaseInversion(invProb, directiveList=[IRLS,betaest,update_Jacobi])
m0 = mrec
# Run inversion # Run inversion
mrec = inv.run(m0) mrec = inv.run(m0)
@@ -117,7 +109,7 @@ def run(N=200, plotIt=True):
axes[0].set_title('Columns of matrix G') axes[0].set_title('Columns of matrix G')
axes[1].plot(mesh.vectorCCx, mtrue, 'b-') axes[1].plot(mesh.vectorCCx, mtrue, 'b-')
axes[1].plot(mesh.vectorCCx, ml2, 'r-') axes[1].plot(mesh.vectorCCx, reg.l2model, 'r-')
#axes[1].legend(('True Model', 'Recovered Model')) #axes[1].legend(('True Model', 'Recovered Model'))
axes[1].set_ylim(-1.0,1.25) axes[1].set_ylim(-1.0,1.25)
@@ -1,22 +1,25 @@
from SimPEG import Mesh, Utils, np, SolverLU from SimPEG import Mesh, Utils, np, SolverLU
## 2D DC forward modeling example with Tensor and Curvilinear Meshes
def run(plotIt=True): def run(plotIt=True):
"""
Mesh: Basic Forward 2D DC Resistivity
=====================================
2D DC forward modeling example with Tensor and Curvilinear Meshes
"""
# Step1: Generate Tensor and Curvilinear Mesh # Step1: Generate Tensor and Curvilinear Mesh
sz = [40,40] sz = [40,40]
# Tensor Mesh
tM = Mesh.TensorMesh(sz) tM = Mesh.TensorMesh(sz)
# Curvilinear Mesh
rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate')) rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
# Step2: Direct Current (DC) operator # Step2: Direct Current (DC) operator
def DCfun(mesh, pts): def DCfun(mesh, pts):
D = mesh.faceDiv D = mesh.faceDiv
G = D.T
sigma = 1e-2*np.ones(mesh.nC) sigma = 1e-2*np.ones(mesh.nC)
Msigi = mesh.getFaceInnerProduct(1./sigma) MsigI = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True)
MsigI = Utils.sdInv(Msigi) A = -D*MsigI*D.T
A = D*MsigI*G
A[-1,-1] /= mesh.vol[-1] # Remove null space A[-1,-1] /= mesh.vol[-1] # Remove null space
rhs = np.zeros(mesh.nC) rhs = np.zeros(mesh.nC)
txind = Utils.meshutils.closestPoints(mesh, pts) txind = Utils.meshutils.closestPoints(mesh, pts)
@@ -37,39 +40,17 @@ def run(plotIt=True):
if not plotIt: return if not plotIt: return
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matplotlib
from matplotlib.mlab import griddata
#Step4: Making Figure #Step4: Making Figure
fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2)) fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
label = ["(a)", "(b)"]
opts = {}
vmin, vmax = phitM.min(), phitM.max() vmin, vmax = phitM.min(), phitM.max()
dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True) dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)
dat = rM.plotImage(phirM, ax=axes[1], clim=(vmin, vmax), grid=True)
#TODO: At the moment Curvilinear Mesh do not have plotimage
Xi = tM.gridCC[:,0].reshape(sz[0], sz[1], order='F')
Yi = tM.gridCC[:,1].reshape(sz[0], sz[1], order='F')
PHIrM = griddata(rM.gridCC[:,0], rM.gridCC[:,1], phirM, Xi, Yi, interp='linear')
axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax)
cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)") cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)")
cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)") cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)")
tM.plotGrid(ax=axes[0], **opts)
axes[0].set_title('TensorMesh') axes[0].set_title('TensorMesh')
rM.plotGrid(ax=axes[1], **opts)
axes[1].set_title('CurvilinearMesh') axes[1].set_title('CurvilinearMesh')
for i in range(2):
axes[i].set_xlim(0.025, 0.975)
axes[i].set_ylim(0.025, 0.975)
axes[i].text(0., 1.0, label[i], fontsize=20)
if i==0:
axes[i].set_ylabel("y")
else:
axes[i].set_ylabel(" ")
axes[i].set_xlabel("x")
plt.show() plt.show()
+41
View File
@@ -0,0 +1,41 @@
from SimPEG import *
from SimPEG.Utils import surface2ind_topo
def run(plotIt=False, nx = 5, ny = 5):
"""
Here we show how to use :code:`Utils.surface2ind_topo` to identify cells below
a topographic surface.
"""
mesh = Mesh.TensorMesh([nx,ny], x0='CC') # 2D mesh
xtopo = np.linspace(mesh.gridN[:,0].min(), mesh.gridN[:,0].max())
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
indcc = surface2ind_topo(mesh, Topo,'CC')
if plotIt:
from matplotlib.pylab import plt
from scipy.interpolate import interp1d
fig, ax = plt.subplots(1,1,figsize=(6,6))
mesh.plotGrid(ax=ax, nodes=True, centers=True)
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)
aveN2CC = Utils.sdiag(mesh.aveN2CC.T.sum(1))*mesh.aveN2CC.T
a = aveN2CC * indcc
a[a > 0] = 1.
a[a < 0.25] = np.nan
a = a.reshape(mesh.vnN, order='F')
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)
plt.show()
if __name__ == '__main__':
run(plotIt=True)
+3 -2
View File
@@ -8,9 +8,9 @@ import EM_FDEM_Analytic_MagDipoleWholespace
import EM_Schenkel_Morrison_Casing import EM_Schenkel_Morrison_Casing
import EM_TDEM_1D_Inversion import EM_TDEM_1D_Inversion
import FLOW_Richards_1D_Celia1990 import FLOW_Richards_1D_Celia1990
import Forward_BasicDirectCurrent
import Inversion_IRLS import Inversion_IRLS
import Inversion_Linear import Inversion_Linear
import Mesh_Basic_ForwardDC
import Mesh_Basic_PlotImage import Mesh_Basic_PlotImage
import Mesh_Basic_Types import Mesh_Basic_Types
import Mesh_Operators_CahnHilliard import Mesh_Operators_CahnHilliard
@@ -20,8 +20,9 @@ import Mesh_QuadTree_HangingNodes
import Mesh_Tensor_Creation import Mesh_Tensor_Creation
import MT_1D_ForwardAndInversion import MT_1D_ForwardAndInversion
import MT_3D_Foward import MT_3D_Foward
import Utils_surface2ind_topo
__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", "Forward_BasicDirectCurrent", "Inversion_IRLS", "Inversion_Linear", "Mesh_Basic_PlotImage", "Mesh_Basic_Types", "Mesh_Operators_CahnHilliard", "Mesh_QuadTree_Creation", "Mesh_QuadTree_FaceDiv", "Mesh_QuadTree_HangingNodes", "Mesh_Tensor_Creation", "MT_1D_ForwardAndInversion", "MT_3D_Foward"] __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", "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 #####
-77
View File
@@ -533,83 +533,6 @@ class ActiveCells(InjectActiveCells):
FutureWarning) FutureWarning)
InjectActiveCells.__init__(self, mesh, indActive, valInactive, nC) InjectActiveCells.__init__(self, mesh, indActive, valInactive, nC)
class InjectActiveCellsTopo(IdentityMap):
"""
Active model parameters. Extend for cells on topography to air cell (only works for tensor mesh)
"""
indActive = None #: Active Cells
valInactive = None #: Values of inactive Cells
nC = None #: Number of cells in the full model
def __init__(self, mesh, indActive, nC=None):
self.mesh = mesh
self.nC = nC or mesh.nC
if indActive.dtype is not bool:
z = np.zeros(self.nC,dtype=bool)
z[indActive] = True
indActive = z
self.indActive = indActive
self.indInactive = np.logical_not(indActive)
inds = np.nonzero(self.indActive)[0]
self.P = sp.csr_matrix((np.ones(inds.size),(inds, range(inds.size))), shape=(self.nC, self.nP))
@property
def shape(self):
return (self.nC, self.nP)
@property
def nP(self):
"""Number of parameters in the model."""
return self.indActive.sum()
def _transform(self, m):
val_temp = np.zeros(self.mesh.nC)
val_temp[self.indActive] = m
valInactive = np.zeros(self.mesh.nC)
#1D
if self.mesh.dim == 1:
z_temp = self.mesh.gridCC
val_temp[~self.indActive] = val_temp[np.argmax(z_temp[self.indActive])]
#2D
elif self.mesh.dim == 2:
act_temp = self.indActive.reshape((self.mesh.nCx, self.mesh.nCy), order = 'F')
val_temp = val_temp.reshape((self.mesh.nCx, self.mesh.nCy), order = 'F')
y_temp = self.mesh.gridCC[:,1].reshape((self.mesh.nCx, self.mesh.nCy), order = 'F')
for i in range(self.mesh.nCx):
act_tempx = act_temp[i,:] == 1
val_temp[i,~act_tempx] = val_temp[i,np.argmax(y_temp[i,act_tempx])]
valInactive[~self.indActive] = Utils.mkvc(val_temp)[~self.indActive]
#3D
elif self.mesh.dim == 3:
act_temp = self.indActive.reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
val_temp = val_temp.reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
z_temp = self.mesh.gridCC[:,2].reshape((self.mesh.nCx*self.mesh.nCy, self.mesh.nCz), order = 'F')
for i in range(self.mesh.nCx*self.mesh.nCy):
act_tempxy = act_temp[i,:] == 1
val_temp[i,~act_tempxy] = val_temp[i,np.argmax(z_temp[i,act_tempxy])]
valInactive[~self.indActive] = Utils.mkvc(val_temp)[~self.indActive]
self.valInactive = valInactive
return self.P*m + self.valInactive
def inverse(self, D):
return self.P.T*D
def deriv(self, m):
return self.P
class ActiveCellsTopo(InjectActiveCellsTopo):
def __init__(self, mesh, indActive, valInactive, nC=None):
warnings.warn(
"`ActiveCellsTopo` is deprecated and will be removed in future versions. Use `InjectActiveCellsTopo` instead",
FutureWarning)
InjectActiveCellsTopo.__init__(self, mesh, indActive, valInactive, nC)
class Weighting(IdentityMap): class Weighting(IdentityMap):
""" """
+2 -97
View File
@@ -2,6 +2,7 @@ from SimPEG import Utils, np
from BaseMesh import BaseRectangularMesh from BaseMesh import BaseRectangularMesh
from DiffOperators import DiffOperators from DiffOperators import DiffOperators
from InnerProducts import InnerProducts from InnerProducts import InnerProducts
from View import CurvView
# Some helper functions. # Some helper functions.
length2D = lambda x: (x[:, 0]**2 + x[:, 1]**2)**0.5 length2D = lambda x: (x[:, 0]**2 + x[:, 1]**2)**0.5
@@ -10,7 +11,7 @@ normalize2D = lambda x: x/np.kron(np.ones((1, 2)), Utils.mkvc(length2D(x), 2))
normalize3D = lambda x: x/np.kron(np.ones((1, 3)), Utils.mkvc(length3D(x), 2)) normalize3D = lambda x: x/np.kron(np.ones((1, 3)), Utils.mkvc(length3D(x), 2))
class CurvilinearMesh(BaseRectangularMesh, DiffOperators, InnerProducts): class CurvilinearMesh(BaseRectangularMesh, DiffOperators, InnerProducts, CurvView):
""" """
CurvilinearMesh is a mesh class that deals with curvilinear meshes. CurvilinearMesh is a mesh class that deals with curvilinear meshes.
@@ -330,102 +331,6 @@ class CurvilinearMesh(BaseRectangularMesh, DiffOperators, InnerProducts):
#############################################
# Plotting Functions #
#############################################
def plotGrid(self, ax=None, nodes=False, faces=False, centers=False, edges=False, lines=True, showIt=False):
"""Plot the nodal, cell-centered and staggered grids for 1,2 and 3 dimensions.
.. plot::
:include-source:
from SimPEG import Mesh, Utils
X, Y = Utils.exampleLrmGrid([3,3],'rotate')
M = Mesh.CurvilinearMesh([X, Y])
M.plotGrid(showIt=True)
"""
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
mkvc = Utils.mkvc
axOpts = {'projection':'3d'} if self.dim == 3 else {}
if ax is None: ax = plt.subplot(111, **axOpts)
NN = self.r(self.gridN, 'N', 'N', 'M')
if self.dim == 2:
if lines:
X1 = np.c_[mkvc(NN[0][:-1, :]), mkvc(NN[0][1:, :]), mkvc(NN[0][:-1, :])*np.nan].flatten()
Y1 = np.c_[mkvc(NN[1][:-1, :]), mkvc(NN[1][1:, :]), mkvc(NN[1][:-1, :])*np.nan].flatten()
X2 = np.c_[mkvc(NN[0][:, :-1]), mkvc(NN[0][:, 1:]), mkvc(NN[0][:, :-1])*np.nan].flatten()
Y2 = np.c_[mkvc(NN[1][:, :-1]), mkvc(NN[1][:, 1:]), mkvc(NN[1][:, :-1])*np.nan].flatten()
X = np.r_[X1, X2]
Y = np.r_[Y1, Y2]
ax.plot(X, Y, 'b-')
if centers:
ax.plot(self.gridCC[:,0],self.gridCC[:,1],'ro')
# Nx = self.r(self.normals, 'F', 'Fx', 'V')
# Ny = self.r(self.normals, 'F', 'Fy', 'V')
# Tx = self.r(self.tangents, 'E', 'Ex', 'V')
# Ty = self.r(self.tangents, 'E', 'Ey', 'V')
# ax.plot(self.gridN[:, 0], self.gridN[:, 1], 'bo')
# nX = np.c_[self.gridFx[:, 0], self.gridFx[:, 0] + Nx[0]*length, self.gridFx[:, 0]*np.nan].flatten()
# nY = np.c_[self.gridFx[:, 1], self.gridFx[:, 1] + Nx[1]*length, self.gridFx[:, 1]*np.nan].flatten()
# ax.plot(self.gridFx[:, 0], self.gridFx[:, 1], 'rs')
# ax.plot(nX, nY, 'r-')
# nX = np.c_[self.gridFy[:, 0], self.gridFy[:, 0] + Ny[0]*length, self.gridFy[:, 0]*np.nan].flatten()
# nY = np.c_[self.gridFy[:, 1], self.gridFy[:, 1] + Ny[1]*length, self.gridFy[:, 1]*np.nan].flatten()
# #ax.plot(self.gridFy[:, 0], self.gridFy[:, 1], 'gs')
# ax.plot(nX, nY, 'g-')
# tX = np.c_[self.gridEx[:, 0], self.gridEx[:, 0] + Tx[0]*length, self.gridEx[:, 0]*np.nan].flatten()
# tY = np.c_[self.gridEx[:, 1], self.gridEx[:, 1] + Tx[1]*length, self.gridEx[:, 1]*np.nan].flatten()
# ax.plot(self.gridEx[:, 0], self.gridEx[:, 1], 'r^')
# ax.plot(tX, tY, 'r-')
# nX = np.c_[self.gridEy[:, 0], self.gridEy[:, 0] + Ty[0]*length, self.gridEy[:, 0]*np.nan].flatten()
# nY = np.c_[self.gridEy[:, 1], self.gridEy[:, 1] + Ty[1]*length, self.gridEy[:, 1]*np.nan].flatten()
# #ax.plot(self.gridEy[:, 0], self.gridEy[:, 1], 'g^')
# ax.plot(nX, nY, 'g-')
elif self.dim == 3:
X1 = np.c_[mkvc(NN[0][:-1, :, :]), mkvc(NN[0][1:, :, :]), mkvc(NN[0][:-1, :, :])*np.nan].flatten()
Y1 = np.c_[mkvc(NN[1][:-1, :, :]), mkvc(NN[1][1:, :, :]), mkvc(NN[1][:-1, :, :])*np.nan].flatten()
Z1 = np.c_[mkvc(NN[2][:-1, :, :]), mkvc(NN[2][1:, :, :]), mkvc(NN[2][:-1, :, :])*np.nan].flatten()
X2 = np.c_[mkvc(NN[0][:, :-1, :]), mkvc(NN[0][:, 1:, :]), mkvc(NN[0][:, :-1, :])*np.nan].flatten()
Y2 = np.c_[mkvc(NN[1][:, :-1, :]), mkvc(NN[1][:, 1:, :]), mkvc(NN[1][:, :-1, :])*np.nan].flatten()
Z2 = np.c_[mkvc(NN[2][:, :-1, :]), mkvc(NN[2][:, 1:, :]), mkvc(NN[2][:, :-1, :])*np.nan].flatten()
X3 = np.c_[mkvc(NN[0][:, :, :-1]), mkvc(NN[0][:, :, 1:]), mkvc(NN[0][:, :, :-1])*np.nan].flatten()
Y3 = np.c_[mkvc(NN[1][:, :, :-1]), mkvc(NN[1][:, :, 1:]), mkvc(NN[1][:, :, :-1])*np.nan].flatten()
Z3 = np.c_[mkvc(NN[2][:, :, :-1]), mkvc(NN[2][:, :, 1:]), mkvc(NN[2][:, :, :-1])*np.nan].flatten()
X = np.r_[X1, X2, X3]
Y = np.r_[Y1, Y2, Y3]
Z = np.r_[Z1, Z2, Z3]
ax.plot(X, Y, 'b', zs=Z)
ax.set_zlabel('x3')
ax.grid(True)
ax.set_xlabel('x1')
ax.set_ylabel('x2')
if showIt: plt.show()
if __name__ == '__main__': if __name__ == '__main__':
nc = 5 nc = 5
h1 = np.cumsum(np.r_[0, np.ones(nc)/(nc)]) h1 = np.cumsum(np.r_[0, np.ones(nc)/(nc)])
+78 -40
View File
@@ -552,7 +552,8 @@ class CurvView(object):
def __init__(self): def __init__(self):
pass pass
def plotGrid(self, length=0.05, showIt=False):
def plotGrid(self, ax=None, nodes=False, faces=False, centers=False, edges=False, lines=True, showIt=False):
"""Plot the nodal, cell-centered and staggered grids for 1,2 and 3 dimensions. """Plot the nodal, cell-centered and staggered grids for 1,2 and 3 dimensions.
@@ -560,60 +561,63 @@ class CurvView(object):
:include-source: :include-source:
from SimPEG import Mesh, Utils from SimPEG import Mesh, Utils
X, Y = Utils.exampleCurvGird([3,3],'rotate') X, Y = Utils.exampleLrmGrid([3,3],'rotate')
M = Mesh.CurvilinearMesh([X, Y]) M = Mesh.CurvilinearMesh([X, Y])
M.plotGrid(showIt=True) M.plotGrid(showIt=True)
""" """
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
axOpts = {'projection':'3d'} if self.dim == 3 else {}
if ax is None: ax = plt.subplot(111, **axOpts)
NN = self.r(self.gridN, 'N', 'N', 'M') NN = self.r(self.gridN, 'N', 'N', 'M')
if self.dim == 2: if self.dim == 2:
fig = plt.figure(2)
fig.clf()
ax = plt.subplot(111)
X1 = np.c_[mkvc(NN[0][:-1, :]), mkvc(NN[0][1:, :]), mkvc(NN[0][:-1, :])*np.nan].flatten()
Y1 = np.c_[mkvc(NN[1][:-1, :]), mkvc(NN[1][1:, :]), mkvc(NN[1][:-1, :])*np.nan].flatten()
X2 = np.c_[mkvc(NN[0][:, :-1]), mkvc(NN[0][:, 1:]), mkvc(NN[0][:, :-1])*np.nan].flatten() if lines:
Y2 = np.c_[mkvc(NN[1][:, :-1]), mkvc(NN[1][:, 1:]), mkvc(NN[1][:, :-1])*np.nan].flatten() X1 = np.c_[mkvc(NN[0][:-1, :]), mkvc(NN[0][1:, :]), mkvc(NN[0][:-1, :])*np.nan].flatten()
Y1 = np.c_[mkvc(NN[1][:-1, :]), mkvc(NN[1][1:, :]), mkvc(NN[1][:-1, :])*np.nan].flatten()
X = np.r_[X1, X2] X2 = np.c_[mkvc(NN[0][:, :-1]), mkvc(NN[0][:, 1:]), mkvc(NN[0][:, :-1])*np.nan].flatten()
Y = np.r_[Y1, Y2] Y2 = np.c_[mkvc(NN[1][:, :-1]), mkvc(NN[1][:, 1:]), mkvc(NN[1][:, :-1])*np.nan].flatten()
plt.plot(X, Y) X = np.r_[X1, X2]
Y = np.r_[Y1, Y2]
plt.hold(True) ax.plot(X, Y, 'b-')
Nx = self.r(self.normals, 'F', 'Fx', 'V') if centers:
Ny = self.r(self.normals, 'F', 'Fy', 'V') ax.plot(self.gridCC[:,0],self.gridCC[:,1],'ro')
Tx = self.r(self.tangents, 'E', 'Ex', 'V')
Ty = self.r(self.tangents, 'E', 'Ey', 'V')
plt.plot(self.gridN[:, 0], self.gridN[:, 1], 'bo') # Nx = self.r(self.normals, 'F', 'Fx', 'V')
# Ny = self.r(self.normals, 'F', 'Fy', 'V')
# Tx = self.r(self.tangents, 'E', 'Ex', 'V')
# Ty = self.r(self.tangents, 'E', 'Ey', 'V')
nX = np.c_[self.gridFx[:, 0], self.gridFx[:, 0] + Nx[0]*length, self.gridFx[:, 0]*np.nan].flatten() # ax.plot(self.gridN[:, 0], self.gridN[:, 1], 'bo')
nY = np.c_[self.gridFx[:, 1], self.gridFx[:, 1] + Nx[1]*length, self.gridFx[:, 1]*np.nan].flatten()
plt.plot(self.gridFx[:, 0], self.gridFx[:, 1], 'rs')
plt.plot(nX, nY, 'r-')
nX = np.c_[self.gridFy[:, 0], self.gridFy[:, 0] + Ny[0]*length, self.gridFy[:, 0]*np.nan].flatten() # nX = np.c_[self.gridFx[:, 0], self.gridFx[:, 0] + Nx[0]*length, self.gridFx[:, 0]*np.nan].flatten()
nY = np.c_[self.gridFy[:, 1], self.gridFy[:, 1] + Ny[1]*length, self.gridFy[:, 1]*np.nan].flatten() # nY = np.c_[self.gridFx[:, 1], self.gridFx[:, 1] + Nx[1]*length, self.gridFx[:, 1]*np.nan].flatten()
#plt.plot(self.gridFy[:, 0], self.gridFy[:, 1], 'gs') # ax.plot(self.gridFx[:, 0], self.gridFx[:, 1], 'rs')
plt.plot(nX, nY, 'g-') # ax.plot(nX, nY, 'r-')
tX = np.c_[self.gridEx[:, 0], self.gridEx[:, 0] + Tx[0]*length, self.gridEx[:, 0]*np.nan].flatten() # nX = np.c_[self.gridFy[:, 0], self.gridFy[:, 0] + Ny[0]*length, self.gridFy[:, 0]*np.nan].flatten()
tY = np.c_[self.gridEx[:, 1], self.gridEx[:, 1] + Tx[1]*length, self.gridEx[:, 1]*np.nan].flatten() # nY = np.c_[self.gridFy[:, 1], self.gridFy[:, 1] + Ny[1]*length, self.gridFy[:, 1]*np.nan].flatten()
plt.plot(self.gridEx[:, 0], self.gridEx[:, 1], 'r^') # #ax.plot(self.gridFy[:, 0], self.gridFy[:, 1], 'gs')
plt.plot(tX, tY, 'r-') # ax.plot(nX, nY, 'g-')
nX = np.c_[self.gridEy[:, 0], self.gridEy[:, 0] + Ty[0]*length, self.gridEy[:, 0]*np.nan].flatten() # tX = np.c_[self.gridEx[:, 0], self.gridEx[:, 0] + Tx[0]*length, self.gridEx[:, 0]*np.nan].flatten()
nY = np.c_[self.gridEy[:, 1], self.gridEy[:, 1] + Ty[1]*length, self.gridEy[:, 1]*np.nan].flatten() # tY = np.c_[self.gridEx[:, 1], self.gridEx[:, 1] + Tx[1]*length, self.gridEx[:, 1]*np.nan].flatten()
#plt.plot(self.gridEy[:, 0], self.gridEy[:, 1], 'g^') # ax.plot(self.gridEx[:, 0], self.gridEx[:, 1], 'r^')
plt.plot(nX, nY, 'g-') # ax.plot(tX, tY, 'r-')
plt.axis('equal')
# nX = np.c_[self.gridEy[:, 0], self.gridEy[:, 0] + Ty[0]*length, self.gridEy[:, 0]*np.nan].flatten()
# nY = np.c_[self.gridEy[:, 1], self.gridEy[:, 1] + Ty[1]*length, self.gridEy[:, 1]*np.nan].flatten()
# #ax.plot(self.gridEy[:, 0], self.gridEy[:, 1], 'g^')
# ax.plot(nX, nY, 'g-')
elif self.dim == 3: elif self.dim == 3:
fig = plt.figure(3)
fig.clf()
ax = fig.add_subplot(111, projection='3d')
X1 = np.c_[mkvc(NN[0][:-1, :, :]), mkvc(NN[0][1:, :, :]), mkvc(NN[0][:-1, :, :])*np.nan].flatten() X1 = np.c_[mkvc(NN[0][:-1, :, :]), mkvc(NN[0][1:, :, :]), mkvc(NN[0][:-1, :, :])*np.nan].flatten()
Y1 = np.c_[mkvc(NN[1][:-1, :, :]), mkvc(NN[1][1:, :, :]), mkvc(NN[1][:-1, :, :])*np.nan].flatten() Y1 = np.c_[mkvc(NN[1][:-1, :, :]), mkvc(NN[1][1:, :, :]), mkvc(NN[1][:-1, :, :])*np.nan].flatten()
Z1 = np.c_[mkvc(NN[2][:-1, :, :]), mkvc(NN[2][1:, :, :]), mkvc(NN[2][:-1, :, :])*np.nan].flatten() Z1 = np.c_[mkvc(NN[2][:-1, :, :]), mkvc(NN[2][1:, :, :]), mkvc(NN[2][:-1, :, :])*np.nan].flatten()
@@ -630,16 +634,50 @@ class CurvView(object):
Y = np.r_[Y1, Y2, Y3] Y = np.r_[Y1, Y2, Y3]
Z = np.r_[Z1, Z2, Z3] Z = np.r_[Z1, Z2, Z3]
plt.plot(X, Y, 'b', zs=Z) ax.plot(X, Y, 'b', zs=Z)
ax.set_zlabel('x3') ax.set_zlabel('x3')
ax.grid(True) ax.grid(True)
ax.hold(False)
ax.set_xlabel('x1') ax.set_xlabel('x1')
ax.set_ylabel('x2') ax.set_ylabel('x2')
if showIt: plt.show() if showIt: plt.show()
def plotImage(self, I, ax=None, showIt=False, grid=False, clim=None):
if self.dim == 3: raise NotImplementedError('This is not yet done!')
import matplotlib.pyplot as plt
import matplotlib
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as colors
import matplotlib.cm as cmx
if ax is None: ax = plt.subplot(111)
jet = cm = plt.get_cmap('jet')
cNorm = colors.Normalize(
vmin=I.min() if clim is None else clim[0],
vmax=I.max() if clim is None else clim[1])
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)
# ax.set_xlim((self.x0[0], self.h[0].sum()))
# ax.set_ylim((self.x0[1], self.h[1].sum()))
Nx = self.r(self.gridN[:,0],'N','N','M')
Ny = self.r(self.gridN[:,1],'N','N','M')
cell = self.r(I,'CC','CC','M')
for ii in range(self.nCx):
for jj in range(self.nCy):
I = [ii,ii+1,ii+1,ii]
J = [jj,jj,jj+1,jj+1]
ax.add_patch(plt.Polygon(np.c_[Nx[I,J],Ny[I,J]], facecolor=scalarMap.to_rgba(cell[ii,jj]), edgecolor='k' if grid else 'none'))
scalarMap._A = [] # http://stackoverflow.com/questions/8342549/matplotlib-add-colorbar-to-a-sequence-of-line-plots
ax.set_xlabel('x')
ax.set_ylabel('y')
if showIt: plt.show()
return [scalarMap]
if __name__ == '__main__': if __name__ == '__main__':
from SimPEG import * from SimPEG import *
+1 -1
View File
@@ -1008,4 +1008,4 @@ class ProjectedGNCG(BFGS, Minimize, Remember):
indx = ((self.xc<=self.lower) & (delx < 0)) | ((self.xc>=self.upper) & (delx > 0)) indx = ((self.xc<=self.lower) & (delx < 0)) | ((self.xc>=self.upper) & (delx > 0))
delx[indx] = 0. delx[indx] = 0.
return delx return delx
+2 -2
View File
@@ -74,7 +74,7 @@ class Property(object):
if linkedMap is None: if linkedMap is None:
return None return None
linkMap = linkMapClass(None) * linkedMap linkMap = linkMapClass(None) * linkedMap
m = getattr(self, '%s'%linkName) m = getattr(self, '%sModel'%linkName)
return linkMap.deriv( m ) return linkMap.deriv( m )
m = getattr(self, '%sModel'%prop.name) m = getattr(self, '%sModel'%prop.name)
@@ -239,7 +239,7 @@ class PropMap(object):
setattr(self, '%sMap'%name, mapping) setattr(self, '%sMap'%name, mapping)
setattr(self, '%sIndex'%name, slices.get(name, slice(nP, nP + mapping.nP))) setattr(self, '%sIndex'%name, slices.get(name, slice(nP, nP + mapping.nP)))
nP += mapping.nP nP += mapping.nP
self.nP = nP self.nP = nP
@property @property
def defaultInvProp(self): def defaultInvProp(self):
+442 -184
View File
@@ -1,4 +1,6 @@
import Utils, Maps, Mesh, numpy as np, scipy.sparse as sp import Utils, Maps, Mesh
import numpy as np
import scipy.sparse as sp
class RegularizationMesh(object): class RegularizationMesh(object):
""" """
@@ -403,7 +405,238 @@ class BaseRegularization(object):
return mD.T * ( self.W.T * ( self.W * ( mD * v) ) ) return mD.T * ( self.W.T * ( self.W * ( mD * v) ) )
class Tikhonov(BaseRegularization): class Simple(BaseRegularization):
"""
Simple regularization that does not include length scales in the derivatives.
"""
mrefInSmooth = False #: include mref in the smoothness?
alpha_s = Utils.dependentProperty('_alpha_s', 1.0, ['_W', '_Wsmall'], "Smallness weight")
alpha_x = Utils.dependentProperty('_alpha_x', 1.0, ['_W', '_Wx'], "Weight for the first derivative in the x direction")
alpha_y = Utils.dependentProperty('_alpha_y', 1.0, ['_W', '_Wy'], "Weight for the first derivative in the y direction")
alpha_z = Utils.dependentProperty('_alpha_z', 1.0, ['_W', '_Wz'], "Weight for the first derivative in the z direction")
cell_weights = 1.
def __init__(self, mesh, mapping=None, indActive=None, **kwargs):
BaseRegularization.__init__(self, mesh, mapping=mapping, indActive=indActive, **kwargs)
if isinstance(self.cell_weights,float):
self.cell_weights = np.ones(self.regmesh.nC) * self.cell_weights
@property
def Wsmall(self):
"""Regularization matrix Wsmall"""
if getattr(self,'_Wsmall', None) is None:
self._Wsmall = Utils.sdiag((self.alpha_s*self.cell_weights)**0.5)
return self._Wsmall
@property
def Wx(self):
"""Regularization matrix Wx"""
if getattr(self, '_Wx', None) is None:
self._Wx = Utils.sdiag((self.alpha_x * (self.regmesh.aveCC2Fx*self.cell_weights))**0.5)*self.regmesh.cellDiffxStencil
return self._Wx
@property
def Wy(self):
"""Regularization matrix Wy"""
if getattr(self, '_Wy', None) is None:
self._Wy = Utils.sdiag((self.alpha_y * (self.regmesh.aveCC2Fy*self.cell_weights))**0.5)*self.regmesh.cellDiffyStencil
return self._Wy
@property
def Wz(self):
"""Regularization matrix Wz"""
if getattr(self, '_Wz', None) is None:
self._Wz = Utils.sdiag((self.alpha_z * (self.regmesh.aveCC2Fz*self.cell_weights))**0.5)*self.regmesh.cellDiffzStencil
return self._Wz
# @property
# def Wsmooth(self):
# """Full smoothness regularization matrix W"""
# print 'wtf why are we using Wsmooth'
# raise NotImplementedError
# if getattr(self, '_Wsmooth', None) is None:
# wlist = (self.Wx,)
# if self.regmesh.dim > 1:
# wlist += (self.Wy,)
# if self.regmesh.dim > 2:
# wlist += (self.Wz,)
# self._Wsmooth = sp.vstack(wlist)
# return self._Wsmooth
#
# @property
# def W(self):
# """Full regularization matrix W"""
# print 'wtf why are we using W'
# if getattr(self, '_W', None) is None:
# wlist = (self.Wsmall, self.Wx)
# if self.regmesh.dim > 1:
# wlist += (self.Wy,)
# if self.regmesh.dim > 2:
# wlist += (self.Wz,)
# self._W = sp.vstack(wlist)
# return self._W
@Utils.timeIt
def _evalSmall(self, m):
r = self.Wsmall * ( self.mapping * (m - self.mref) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmallDeriv(self, m):
r = self.Wsmall * ( self.mapping * (m - self.mref) )
return r.T * ( self.Wsmall * self.mapping.deriv(m - self.mref) )
@Utils.timeIt
def _evalSmall2Deriv(self, m, v = None):
rDeriv = self.Wsmall * ( self.mapping.deriv(m - self.mref) )
if v is not None:
return rDeriv.T * (rDeriv * v)
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothx(self, m):
if self.mrefInSmooth == True:
r = self.Wx * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wx * ( self.mapping * (m) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmoothy(self, m):
if self.mrefInSmooth == True:
r = self.Wy * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wy * ( self.mapping * (m) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmoothz(self, m):
if self.mrefInSmooth == True:
r = self.Wz * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wz * ( self.mapping * (m) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmooth(self, m):
phiSmooth = self._evalSmoothx(m)
if self.regmesh.dim > 1:
phiSmooth += self._evalSmoothy(m)
if self.regmesh.dim > 2:
phiSmooth += self._evalSmoothz(m)
return phiSmooth
@Utils.timeIt
def _evalSmoothxDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wx * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wx * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wx * ( self.mapping * m )
return r.T * ( self.Wx * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothx2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wx * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wx * ( self.mapping.deriv(m) )
if v is not None:
return rDeriv.T * ( rDeriv * v )
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothyDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wy * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wy * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wy * ( self.mapping * m )
return r.T * ( self.Wy * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothy2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wy * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wy * ( self.mapping.deriv(m) )
if v is not None:
return rDeriv.T * ( rDeriv * v )
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothzDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wz * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wz * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wz * ( self.mapping * m )
return r.T * ( self.Wz * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothz2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wz * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wz * ( self.mapping.deriv(m) )
if v is not None:
return rDeriv.T * ( rDeriv * v )
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothDeriv(self, m):
deriv = self._evalSmoothxDeriv(m)
if self.regmesh.dim > 1:
deriv += self._evalSmoothyDeriv(m)
if self.regmesh.dim > 2:
deriv += self._evalSmoothzDeriv(m)
return deriv
@Utils.timeIt
def _evalSmooth2Deriv(self, m, v=None):
deriv = self._evalSmoothx2Deriv(m, v)
if self.regmesh.dim > 1:
deriv += self._evalSmoothy2Deriv(m, v)
if self.regmesh.dim > 2:
deriv += self._evalSmoothz2Deriv(m, v)
return deriv
@Utils.timeIt
def eval(self, m):
return self._evalSmall(m) + self._evalSmooth(m)
@Utils.timeIt
def evalDeriv(self, m):
"""
The regularization is:
.. math::
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top W(m-m_\\text{ref})}
So the derivative is straight forward:
.. math::
R(m) = \mathbf{W^\\top W (m-m_\\text{ref})}
"""
return self._evalSmallDeriv(m) + self._evalSmoothDeriv(m)
@Utils.timeIt
def eval2Deriv(self, m, v=None):
return self._evalSmall2Deriv(m, v) + self._evalSmooth2Deriv(m, v)
class Tikhonov(Simple):
""" """
L2 Tikhonov regularization with both smallness and smoothness (first order L2 Tikhonov regularization with both smallness and smoothness (first order
derivative) contributions. derivative) contributions.
@@ -493,56 +726,131 @@ class Tikhonov(BaseRegularization):
self._Wzz = Utils.sdiag((self.regmesh.vol*self.alpha_zz)**0.5)*self.regmesh.faceDiffz*self.regmesh.cellDiffz self._Wzz = Utils.sdiag((self.regmesh.vol*self.alpha_zz)**0.5)*self.regmesh.faceDiffz*self.regmesh.cellDiffz
return self._Wzz return self._Wzz
@property @property
def Wsmooth(self): def Wsmooth2(self):
"""Full smoothness regularization matrix W""" """Full smoothness regularization matrix W"""
if getattr(self, '_Wsmooth', None) is None: if getattr(self, '_Wsmooth', None) is None:
wlist = (self.Wx, self.Wxx) wlist = (self.Wxx)
if self.regmesh.dim > 1: if self.regmesh.dim > 1:
wlist += (self.Wy, self.Wyy) wlist += (self.Wyy)
if self.regmesh.dim > 2: if self.regmesh.dim > 2:
wlist += (self.Wz, self.Wzz) wlist += (self.Wzz)
self._Wsmooth = sp.vstack(wlist) self._Wsmooth = sp.vstack(wlist)
return self._Wsmooth return self._Wsmooth
@property
def W(self):
"""Full regularization matrix W"""
if getattr(self, '_W', None) is None:
wlist = (self.Wsmall, self.Wsmooth)
self._W = sp.vstack(wlist)
return self._W
@Utils.timeIt @Utils.timeIt
def _evalSmall(self, m): def _evalSmoothxx(self, m):
r = self.Wsmall * ( self.mapping * (m - self.mref) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmooth(self, m):
if self.mrefInSmooth == True: if self.mrefInSmooth == True:
r = self.Wsmooth * ( self.mapping * (m - self.mref) ) r = self.Wxx * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False: elif self.mrefInSmooth == False:
r = self.Wsmooth * ( self.mapping * (m) ) r = self.Wxx * ( self.mapping * (m) )
return 0.5 * r.dot(r) return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmoothyy(self, m):
if self.mrefInSmooth == True:
r = self.Wyy * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wyy * ( self.mapping * (m) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmoothzz(self, m):
if self.mrefInSmooth == True:
r = self.Wzz * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wzz * ( self.mapping * (m) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmooth2(self, m):
phiSmooth2 = self._evalSmoothxx(m)
if self.regmesh.dim > 1:
phiSmooth2 += self._evalSmoothyy(m)
if self.regmesh.dim > 2:
phiSmooth2 += self._evalSmoothzz(m)
return phiSmooth2
@Utils.timeIt
def _evalSmoothxxDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wxx * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wxx * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wxx * ( self.mapping * m )
return r.T * ( self.Wxx * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothyyDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wyy * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wyy * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wyy * ( self.mapping * m )
return r.T * ( self.Wyy * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothzzDeriv(self, m):
if self.mrefInSmooth == True:
r = self.Wzz * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wzz * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wzz * ( self.mapping * m )
return r.T * ( self.Wzz * self.mapping.deriv(m) )
@Utils.timeIt
def _evalSmoothxx2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wxx * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wxx * self.mapping.deriv(m)
if v is not None:
return rDeriv.T * (rDeriv * v)
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothyy2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wyy * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wyy * self.mapping.deriv(m)
if v is not None:
return rDeriv.T * (rDeriv * v)
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothzz2Deriv(self, m, v=None):
if self.mrefInSmooth == True:
rDeriv = self.Wzz * ( self.mapping.deriv( m - self.mref ) )
elif self.mrefInSmooth == False:
rDeriv = self.Wzz * self.mapping.deriv(m)
if v is not None:
return rDeriv.T * (rDeriv * v)
return rDeriv.T * rDeriv
@Utils.timeIt
def _evalSmoothDeriv2(self, m):
deriv = self._evalSmoothxxDeriv(m)
if self.regmesh.dim > 1:
deriv += self._evalSmoothyyDeriv(m)
if self.regmesh.dim > 2:
deriv += self._evalSmoothzzDeriv(m)
return deriv
@Utils.timeIt
def _evalSmooth2Deriv2(self, m, v=None):
deriv = self._evalSmoothxx2Deriv(m, v)
if self.regmesh.dim > 1:
deriv += self._evalSmoothyy2Deriv(m, v)
if self.regmesh.dim > 2:
deriv += self._evalSmoothzz2Deriv(m, v)
return deriv
@Utils.timeIt @Utils.timeIt
def eval(self, m): def eval(self, m):
return self._evalSmall(m) + self._evalSmooth(m) return self._evalSmall(m) + self._evalSmooth(m) + self._evalSmooth2(m)
@Utils.timeIt
def _evalSmallDeriv(self,m):
r = self.Wsmall * ( self.mapping * (m - self.mref) )
return r.T * ( self.Wsmall * self.mapping.deriv(m - self.mref) )
@Utils.timeIt
def _evalSmoothDeriv(self,m):
if self.mrefInSmooth == True:
r = self.Wsmooth * ( self.mapping * ( m - self.mref ) )
return r.T * ( self.Wsmooth * self.mapping.deriv(m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wsmooth * ( self.mapping * m )
return r.T * ( self.Wsmooth * self.mapping.deriv(m) )
@Utils.timeIt @Utils.timeIt
def evalDeriv(self, m): def evalDeriv(self, m):
@@ -560,184 +868,134 @@ class Tikhonov(BaseRegularization):
R(m) = \mathbf{W^\\top W (m-m_\\text{ref})} R(m) = \mathbf{W^\\top W (m-m_\\text{ref})}
""" """
return self._evalSmallDeriv(m) + self._evalSmoothDeriv(m) return self._evalSmallDeriv(m) + self._evalSmoothDeriv(m) + self._evalSmoothDeriv2(m)
def eval2Deriv(self, m, v=None):
"""
The regularization is:
.. math::
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top W(m-m_\\text{ref})}
So the derivative is straight forward:
.. math::
R(m) = \mathbf{W^\\top W (m-m_\\text{ref})}
"""
return self._evalSmall2Deriv(m, v) + self._evalSmooth2Deriv(m, v) + self._evalSmooth2Deriv2(m, v)
class Simple(Tikhonov):
class Sparse(Simple):
""" """
Simple regularization that does not include length scales in the derivatives. The regularization is:
.. math::
R(m) = \\frac{1}{2}\mathbf{(m-m_\\text{ref})^\\top W^\\top R^\\top R W(m-m_\\text{ref})}
where the IRLS weight
.. math::
R = \eta TO FINISH LATER!!!
So the derivative is straight forward:
.. math::
R(m) = \mathbf{W^\\top R^\\top R W (m-m_\\text{ref})}
The IRLS weights are recomputed after each beta solves.
It is strongly recommended to do a few Gauss-Newton iterations
before updating.
""" """
mrefInSmooth = False #: SMOOTH and SMOOTH_MOD_DIF options # set default values
alpha_s = Utils.dependentProperty('_alpha_s', 1.0, ['_W', '_Wsmall'], "Smallness weight") eps_p = 1e-1 # Threshold value for the model norm
alpha_x = Utils.dependentProperty('_alpha_x', 1.0, ['_W', '_Wx'], "Weight for the first derivative in the x direction") eps_q = 1e-1 # Threshold value for the model gradient norm
alpha_y = Utils.dependentProperty('_alpha_y', 1.0, ['_W', '_Wy'], "Weight for the first derivative in the y direction") curModel = None # Requires model to compute the weights
alpha_z = Utils.dependentProperty('_alpha_z', 1.0, ['_W', '_Wz'], "Weight for the first derivative in the z direction") l2model = None
wght = 1. gamma = 1. # Model norm scaling to smooth out convergence
norms = [0., 2., 2., 2.] # Values for norm on (m, dmdx, dmdy, dmdz)
cell_weights = 1. # Consider overwriting with sensitivity weights
def __init__(self, mesh, mapping=None, indActive=None, **kwargs): def __init__(self, mesh, mapping=None, indActive=None, **kwargs):
BaseRegularization.__init__(self, mesh, mapping=mapping, indActive=indActive, **kwargs) Simple.__init__(self, mesh, mapping=mapping, indActive=indActive, **kwargs)
if isinstance(self.wght,float): if isinstance(self.cell_weights,float):
self.wght = np.ones(self.regmesh.nC) * self.wght self.cell_weights = np.ones(self.regmesh.nC) * self.cell_weights
@property @property
def Wsmall(self): def Wsmall(self):
"""Regularization matrix Wsmall""" """Regularization matrix Wsmall"""
if getattr(self,'_Wsmall', None) is None: if getattr(self,'_Wsmall', None) is None:
self._Wsmall = Utils.sdiag((self.regmesh.vol*self.alpha_s*self.wght)**0.5) if getattr(self, 'curModel', None) is None:
self.Rs = Utils.speye(self.regmesh.nC)
else:
f_m = self.mapping * (self.curModel - self.reg.mref)
self.rs = self.R(f_m , self.eps_p, self.norms[0])
self.Rs = Utils.sdiag( self.rs )
self._Wsmall = Utils.sdiag((self.alpha_s*self.gamma*self.cell_weights)**0.5)*self.Rs
return self._Wsmall return self._Wsmall
@property @property
def Wx(self): def Wx(self):
"""Regularization matrix Wx""" """Regularization matrix Wx"""
if getattr(self, '_Wx', None) is None: if getattr(self,'_Wx', None) is None:
self._Wx = Utils.sdiag((self.regmesh.aveCC2Fx * self.regmesh.vol*self.alpha_x*(self.regmesh.aveCC2Fx*self.wght))**0.5)*self.regmesh.cellDiffxStencil if getattr(self, 'curModel', None) is None:
self.Rx = Utils.speye(self.regmesh.cellDiffxStencil.shape[0])
else:
f_m = self.regmesh.cellDiffxStencil * (self.mapping * self.curModel)
self.rx = self.R( f_m , self.eps_q, self.norms[1])
self.Rx = Utils.sdiag( self.rx )
self._Wx = Utils.sdiag(( self.alpha_x*self.gamma*(self.regmesh.aveCC2Fx*self.cell_weights))**0.5)*self.Rx*self.regmesh.cellDiffxStencil
return self._Wx return self._Wx
@property @property
def Wy(self): def Wy(self):
"""Regularization matrix Wy""" """Regularization matrix Wy"""
if getattr(self, '_Wy', None) is None: if getattr(self,'_Wy', None) is None:
self._Wy = Utils.sdiag((self.regmesh.aveCC2Fy * self.regmesh.vol * self.alpha_y*(self.regmesh.aveCC2Fy*self.wght))**0.5)*self.regmesh.cellDiffyStencil if getattr(self, 'curModel', None) is None:
self.Ry = Utils.speye(self.regmesh.cellDiffyStencil.shape[0])
else:
f_m = self.regmesh.cellDiffyStencil * (self.mapping * self.curModel)
self.ry = self.R( f_m , self.eps_q, self.norms[2])
self.Ry = Utils.sdiag( self.ry )
self._Wy = Utils.sdiag((self.alpha_y*self.gamma*(self.regmesh.aveCC2Fy*self.cell_weights))**0.5)*self.Ry*self.regmesh.cellDiffyStencil
return self._Wy return self._Wy
@property @property
def Wz(self): def Wz(self):
"""Regularization matrix Wz""" """Regularization matrix Wz"""
if getattr(self, '_Wz', None) is None: if getattr(self,'_Wz', None) is None:
self._Wz = Utils.sdiag((self.regmesh.aveCC2Fz * self.regmesh.vol*self.alpha_z*(self.regmesh.aveCC2Fz*self.wght))**0.5)*self.regmesh.cellDiffzStencil if getattr(self, 'curModel', None) is None:
self.Rz = Utils.speye(self.regmesh.cellDiffzStencil.shape[0])
else:
f_m = self.regmesh.cellDiffzStencil * (self.mapping * self.curModel)
self.rz = self.R( f_m , self.eps_q, self.norms[3])
self.Rz = Utils.sdiag( self.rz )
self._Wz = Utils.sdiag((self.alpha_z*self.gamma*(self.regmesh.aveCC2Fz*self.cell_weights))**0.5)*self.Rz*self.regmesh.cellDiffzStencil
return self._Wz return self._Wz
@property
def Wsmooth(self):
"""Full smoothness regularization matrix W"""
if getattr(self, '_Wsmooth', None) is None:
wlist = (self.Wx,)
if self.regmesh.dim > 1:
wlist += (self.Wy,)
if self.regmesh.dim > 2:
wlist += (self.Wz,)
self._Wsmooth = sp.vstack(wlist)
return self._Wsmooth
@property
def W(self):
"""Full regularization matrix W"""
if getattr(self, '_W', None) is None:
wlist = (self.Wsmall, self.Wsmooth)
self._W = sp.vstack(wlist)
return self._W
@Utils.timeIt
def _evalSmall(self, m):
r = self.Wsmall * ( self.mapping * (m - self.mref) )
return 0.5 * r.dot(r)
@Utils.timeIt
def _evalSmooth(self, m):
if self.mrefInSmooth == True:
r = self.Wsmooth * ( self.mapping * (m - self.mref) )
elif self.mrefInSmooth == False:
r = self.Wsmooth * ( self.mapping * m)
return 0.5 * r.dot(r)
class Sparse(Simple):
# set default values
eps_p = 1e-1
eps_q = 1e-1
curModel = None # use a model to compute the weights
gamma = 1.
norms = [0., 2., 2., 2.]
wght = 1.
def __init__(self, mesh, mapping=None, indActive=None, **kwargs):
Simple.__init__(self, mesh, mapping=mapping, indActive=indActive, **kwargs)
if isinstance(self.wght,float):
self.wght = np.ones(self.regmesh.nC) * self.wght
@property
def Wsmall(self):
"""Regularization matrix Wsmall"""
if getattr(self, 'curModel', None) is None:
self.Rs = Utils.speye(self.regmesh.nC)
else:
f_m = self.curModel - self.reg.mref
self.rs = self.R(f_m , self.eps_p, self.norms[0])
#print "Min rs: " + str(np.max(self.rs)) + "Max rs: " + str(np.min(self.rs))
self.Rs = Utils.sdiag( self.rs )
return Utils.sdiag((self.regmesh.vol*self.alpha_s*self.gamma*self.wght)**0.5)*self.Rs
@property
def Wx(self):
"""Regularization matrix Wx"""
if getattr(self, 'curModel', None) is None:
self.Rx = Utils.speye(self.regmesh.cellDiffxStencil.shape[0])
else:
f_m = self.regmesh.cellDiffxStencil * self.curModel
self.rx = self.R( f_m , self.eps_q, self.norms[1])
self.Rx = Utils.sdiag( self.rx )
return Utils.sdiag(( (self.regmesh.aveCC2Fx * self.regmesh.vol) *self.alpha_x*self.gamma*(self.regmesh.aveCC2Fx*self.wght))**0.5)*self.Rx*self.regmesh.cellDiffxStencil
@property
def Wy(self):
"""Regularization matrix Wy"""
if getattr(self, 'curModel', None) is None:
self.Ry = Utils.speye(self.regmesh.cellDiffyStencil.shape[0])
else:
f_m = self.regmesh.cellDiffyStencil * self.curModel
self.ry = self.R( f_m , self.eps_q, self.norms[2])
self.Ry = Utils.sdiag( self.ry )
return Utils.sdiag(((self.regmesh.aveCC2Fy * self.regmesh.vol)*self.alpha_y*self.gamma*(self.regmesh.aveCC2Fy*self.wght))**0.5)*self.Ry*self.regmesh.cellDiffyStencil
@property
def Wz(self):
"""Regularization matrix Wz"""
if getattr(self, 'curModel', None) is None:
self.Rz = Utils.speye(self.regmesh.cellDiffzStencil.shape[0])
else:
f_m = self.regmesh.cellDiffzStencil * self.curModel
self.rz = self.R( f_m , self.eps_q, self.norms[3])
self.Rz = Utils.sdiag( self.rz )
return Utils.sdiag(((self.regmesh.aveCC2Fz * self.regmesh.vol)*self.alpha_z*self.gamma*(self.regmesh.aveCC2Fz*self.wght))**0.5)*self.Rz*self.regmesh.cellDiffzStencil
@property
def Wsmooth(self):
"""Full smoothness regularization matrix W"""
#if getattr(self, '_Wsmooth', None) is None:
wlist = (self.Wx,)
if self.regmesh.dim > 1:
wlist += (self.Wy,)
if self.regmesh.dim > 2:
wlist += (self.Wz,)
#self._Wsmooth = sp.vstack(wlist)
return sp.vstack(wlist)
@property
def W(self):
"""Full regularization matrix W"""
if getattr(self, '_W', None) is None:
wlist = (self.Wsmall, self.Wsmooth)
self._W = sp.vstack(wlist)
return self._W
def R(self, f_m , eps, exponent): def R(self, f_m , eps, exponent):
# Eta scaling is important for mix-norms...do not mess with it
eta = (eps**(1.-exponent/2.))**0.5 eta = (eps**(1.-exponent/2.))**0.5
r = eta / (f_m**2.+ eps**2.)**((1.-exponent/2.)/2.) r = eta / (f_m**2.+ eps**2.)**((1.-exponent/2.)/2.)
+1
View File
@@ -7,3 +7,4 @@ from CounterUtils import *
import ModelBuilder import ModelBuilder
import SolverUtils import SolverUtils
from coordutils import * from coordutils import *
from modelutils import *
+63
View File
@@ -0,0 +1,63 @@
from matutils import mkvc, ndgrid
import numpy as np
def surface2ind_topo(mesh, topo, gridLoc='CC'):
# def genActiveindfromTopo(mesh, topo):
"""
Get active indices from topography
"""
if mesh.dim == 3:
from scipy.interpolate import NearestNDInterpolator
Ftopo = NearestNDInterpolator(topo[:,:2], topo[:,2])
if gridLoc == 'CC':
XY = ndgrid(mesh.vectorCCx, mesh.vectorCCy)
Zcc = mesh.gridCC[:,2].reshape((np.prod(mesh.vnC[:2]), mesh.nCz), order='F')
gridTopo = Ftopo(XY)
actind = [gridTopo[ixy] <= Zcc[ixy,:] for ixy in range(np.prod(mesh.vnC[0]))]
actind = np.hstack(actind)
elif gridLoc == 'N':
XY = ndgrid(mesh.vectorNx, mesh.vectorNy)
gridTopo = Ftopo(XY).reshape(mesh.vnN[:2], order='F')
if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
raise NotImplementedError('Nodal surface2ind_topo not implemented for %s mesh'%mesh._meshType)
Nz = mesh.vectorNz[1:] # TODO: this will only work for tensor meshes
actind = np.array([False]*mesh.nC).reshape(mesh.vnC, order='F')
for ii in range(mesh.nCx):
for jj in range(mesh.nCy):
actind[ii,jj,:] = [np.all(gridTopo[ii:ii+2, jj:jj+2] >= Nz[kk]) for kk in range(len(Nz)) ]
elif mesh.dim == 2:
from scipy.interpolate import interp1d
Ftopo = interp1d(topo[:,0], topo[:,1])
if gridLoc == 'CC':
gridTopo = Ftopo(mesh.gridCC[:,0])
actind = mesh.gridCC[:,1] <= gridTopo
elif gridLoc == 'N':
gridTopo = Ftopo(mesh.vectorNx)
if mesh._meshType not in ['TENSOR', 'CYL', 'BASETENSOR']:
raise NotImplementedError('Nodal surface2ind_topo not implemented for %s mesh'%mesh._meshType)
Ny = mesh.vectorNy[1:] # TODO: this will only work for tensor meshes
actind = np.array([False]*mesh.nC).reshape(mesh.vnC, order='F')
for ii in range(mesh.nCx):
actind[ii,:] = [np.all(gridTopo[ii:ii+2] > Ny[kk]) for kk in range(len(Ny)) ]
else:
raise NotImplementedError('surface2ind_topo not implemented for 1D mesh')
return mkvc(actind)
+2 -2
View File
@@ -20,8 +20,8 @@ INPUT:
loc = Location of spheres [[x1,y1,z1],[x2,y2,z2]] loc = Location of spheres [[x1,y1,z1],[x2,y2,z2]]
radi = Radius of spheres [r1,r2] radi = Radius of spheres [r1,r2]
param = Conductivity of background and two spheres [m0,m1,m2] param = Conductivity of background and two spheres [m0,m1,m2]
stype = survey type "pdp" (pole dipole) or "dpdp" (dipole dipole) surveyType = survey type 'pole-dipole' or 'dipole-dipole'
dtype = Data type "appr" (app res) | "appc" (app cond) | "volt" (potential) unitType = Data type "appResistivity" | "appConductivity" | "volt"
Created by @fourndo Created by @fourndo
+25
View File
@@ -0,0 +1,25 @@
.. _examples_Mesh_Basic_ForwardDC:
.. --------------------------------- ..
.. ..
.. THIS FILE IS AUTO GENEREATED ..
.. ..
.. SimPEG/Examples/__init__.py ..
.. ..
.. --------------------------------- ..
Mesh: Basic Forward 2D DC Resistivity
=====================================
2D DC forward modeling example with Tensor and Curvilinear Meshes
.. plot::
from SimPEG import Examples
Examples.Mesh_Basic_ForwardDC.run()
.. literalinclude:: ../../SimPEG/Examples/Mesh_Basic_ForwardDC.py
:language: python
:linenos:
@@ -1,4 +1,4 @@
.. _examples_Forward_BasicDirectCurrent: .. _examples_Utils_surface2ind_topo:
.. --------------------------------- .. .. --------------------------------- ..
.. .. .. ..
@@ -8,14 +8,17 @@
.. .. .. ..
.. --------------------------------- .. .. --------------------------------- ..
Forward BasicDirectCurrent
========================== Here we show how to use :code:`Utils.surface2ind_topo` to identify cells below
a topographic surface.
.. plot:: .. plot::
from SimPEG import Examples from SimPEG import Examples
Examples.Forward_BasicDirectCurrent.run() Examples.Utils_surface2ind_topo.run()
.. literalinclude:: ../../SimPEG/Examples/Forward_BasicDirectCurrent.py .. literalinclude:: ../../SimPEG/Examples/Utils_surface2ind_topo.py
:language: python :language: python
:linenos: :linenos:
+29
View File
@@ -1,6 +1,7 @@
import unittest import unittest
from SimPEG import * from SimPEG import *
from scipy.constants import mu_0 from scipy.constants import mu_0
from SimPEG import Tests
class MyPropMap(Maps.PropMap): class MyPropMap(Maps.PropMap):
@@ -187,6 +188,34 @@ class TestPropMaps(unittest.TestCase):
MyReciprocalPropMap([('sigma', iMap), ('mu', iMap)]) # This should be fine MyReciprocalPropMap([('sigma', iMap), ('mu', iMap)]) # This should be fine
def test_linked_derivs_sigma(self):
mesh = Mesh.TensorMesh([4,5], x0='CC')
mapping = Maps.ExpMap(mesh)
propmap = MyReciprocalPropMap([('rho', mapping)])
x0 = np.random.rand(mesh.nC)
m = propmap(x0)
# test Sigma
testme = lambda v: [1./(m.rhoMap*v), m.sigmaDeriv]
print 'Testing Rho from Sigma'
Tests.checkDerivative(testme, x0, dx=0.01*x0, num=5, plotIt=False)
def test_linked_derivs_rho(self):
mesh = Mesh.TensorMesh([4,5], x0='CC')
mapping = Maps.ExpMap(mesh)
propmap = MyReciprocalPropMap([('sigma', mapping)])
x0 = np.random.rand(mesh.nC)
m = propmap(x0)
# test Sigma
testme = lambda v: [1./(m.sigmaMap*v), m.rhoDeriv]
print 'Testing Rho from Sigma'
Tests.checkDerivative(testme, x0, dx=0.01*x0, num=5, plotIt=False)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()