mirror of
https://github.com/wassname/simpeg.git
synced 2026-09-14 11:35:32 +08:00
Compare commits
63
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a0c9584c55 | ||
|
|
2d992f32d4 | ||
|
|
3f3b2e9232 | ||
|
|
ea5064902c | ||
|
|
4b81ce33f0 | ||
|
|
6a02cc3e99 | ||
|
|
51d82eee26 | ||
|
|
f6b49c680a | ||
|
|
339543b893 | ||
|
|
44ad57e90d | ||
|
|
d98eef2560 | ||
|
|
2c87a50d29 | ||
|
|
beca0203df | ||
|
|
e25b496ab0 | ||
|
|
e5ec512517 | ||
|
|
342414bd25 | ||
|
|
8936fa4021 | ||
|
|
d0a65dda1b | ||
|
|
a506d5c6be | ||
|
|
10c8791514 | ||
|
|
c88263234b | ||
|
|
d5219be3d8 | ||
|
|
029171fb1d | ||
|
|
a690cab131 | ||
|
|
c1b1c2467f | ||
|
|
11e6b452c9 | ||
|
|
73c219ff5c | ||
|
|
abd919e862 | ||
|
|
6e00b4c2fe | ||
|
|
906cca30f3 | ||
|
|
0a714663d3 | ||
|
|
cb042ac938 | ||
|
|
f7c46ed83b | ||
|
|
52747c0926 | ||
|
|
d8eeb7cd05 | ||
|
|
8278230476 | ||
|
|
069127333d | ||
|
|
79e1378009 | ||
|
|
4e296c4cd5 | ||
|
|
5e1de61a71 | ||
|
|
00bbe0f35e | ||
|
|
3d1dfc13d7 | ||
|
|
a6e995e9fb | ||
|
|
056dc09fa6 | ||
|
|
00db6746d4 | ||
|
|
028a16a45a | ||
|
|
c83b460672 | ||
|
|
225394f74e | ||
|
|
f55d9573a6 | ||
|
|
d8bfb27415 | ||
|
|
79183ae9fb | ||
|
|
606488d152 | ||
|
|
23d2783bc1 | ||
|
|
b58ba55ffd | ||
|
|
0d6fe5f7a1 | ||
|
|
90b0301408 | ||
|
|
083742cb40 | ||
|
|
8a18e479ab | ||
|
|
f15a628136 | ||
|
|
fb60f45a3c | ||
|
|
f59cfa9481 | ||
|
|
a220c75d78 | ||
|
|
936a7aaadc |
+96
-54
@@ -169,7 +169,7 @@ def readUBC_DC2DModel(fileName):
|
||||
|
||||
return model
|
||||
|
||||
def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
|
||||
def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None, cblabel=True, axlabel = True, colorbar = True, contour = None):
|
||||
"""
|
||||
Read list of 2D tx-rx location and plot a speudo-section of apparent
|
||||
resistivity.
|
||||
@@ -192,9 +192,6 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
|
||||
from scipy.interpolate import griddata
|
||||
import pylab as plt
|
||||
|
||||
# Set depth to 0 for now
|
||||
z0 = 0.
|
||||
|
||||
# Pre-allocate
|
||||
midx = []
|
||||
midz = []
|
||||
@@ -259,38 +256,53 @@ def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
|
||||
midx = np.hstack([midx, ( Cmid + Pmid )/2 ])
|
||||
midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + (Tx[0][2] + Tx[1][2])/2 ])
|
||||
|
||||
ax = axs
|
||||
|
||||
# Grid points
|
||||
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')
|
||||
|
||||
|
||||
# Scale the color scheme
|
||||
if clim == None:
|
||||
vmin, vmax = rho.min(), rho.max()
|
||||
else:
|
||||
vmin, vmax = clim[0], clim[1]
|
||||
|
||||
# Plot data
|
||||
grid_rho = np.ma.masked_where(np.isnan(grid_rho), grid_rho)
|
||||
ph = plt.pcolormesh(grid_x[:,0],grid_z[0,:],grid_rho.T, clim=(vmin, vmax))
|
||||
cbar = plt.colorbar(format="$10^{%.1f}$",fraction=0.04,orientation="horizontal")
|
||||
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)
|
||||
|
||||
if contour is not None:
|
||||
plt.contour(grid_x,grid_z,grid_rho,levels = contour,colors = 'r', vmin = vmin, vmax = vmax)
|
||||
|
||||
# Add scatter points
|
||||
axs.scatter(midx,midz,s=10,c=rho.T, vmin = vmin, vmax = vmax)
|
||||
|
||||
if colorbar:
|
||||
|
||||
if dtype == 'volt':
|
||||
cbar = plt.colorbar(ph, ax = axs, format="%4.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)
|
||||
else:
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
# Plot apparent resistivity
|
||||
ax.scatter(midx,midz,s=10,c=rho.T, vmin =vmin, vmax = vmax, clim=(vmin, vmax))
|
||||
|
||||
#ax.set_xticklabels([])
|
||||
#ax.set_yticklabels([])
|
||||
if not axlabel:
|
||||
axs.set_xticklabels([])
|
||||
axs.set_yticklabels([])
|
||||
|
||||
plt.gca().set_aspect('equal', adjustable='box')
|
||||
|
||||
@@ -448,15 +460,15 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
|
||||
survey = DC.SurveyDC(SrcList)
|
||||
return survey, Tx, Rx
|
||||
|
||||
def writeUBC_DCobs(fileName, DCsurvey, dtype, stype):
|
||||
def writeUBC_DCobs(fileName, DCsurvey, dtype='3D', stype='SURFACE', iptype = 0):
|
||||
"""
|
||||
Write UBC GIF DCIP 2D or 3D observation file
|
||||
|
||||
Input:
|
||||
:string fileName -> including path where the file is written out
|
||||
:DCsurvey -> DC survey class object
|
||||
:string dtype -> either '2D' | '3D'
|
||||
:string stype -> either 'SURFACE' | 'GENERAL'
|
||||
:string fileName -> including path where the file is written out
|
||||
:DCsurvey DC survey class object
|
||||
:string dtype -> either '2D' | '3D'
|
||||
:string stype -> either 'SURFACE' | 'GENERAL'
|
||||
|
||||
Output:
|
||||
:param UBC2D-Data file
|
||||
@@ -471,10 +483,16 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype, stype):
|
||||
|
||||
assert (dtype=='2D') | (dtype=='3D'), "Data must be either '2D' | '3D'"
|
||||
assert (stype=='SURFACE') | (stype=='GENERAL') | (stype=='SIMPLE'), "Data must be either 'SURFACE' | 'GENERAL' | 'SIMPLE'"
|
||||
|
||||
|
||||
fid = open(fileName,'w')
|
||||
fid.write('! ' + stype + ' FORMAT\n')
|
||||
|
||||
|
||||
|
||||
if iptype!=0:
|
||||
fid.write('IPTYPE=%i\n'%iptype)
|
||||
|
||||
else:
|
||||
fid.write('! ' + stype + ' FORMAT\n')
|
||||
|
||||
count = 0
|
||||
|
||||
for ii in range(DCsurvey.nSrc):
|
||||
@@ -498,7 +516,7 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype, stype):
|
||||
B = np.repeat(tx[0,1],M.shape[0],axis=0)
|
||||
M = M[:,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')
|
||||
|
||||
|
||||
@@ -506,18 +524,25 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype, stype):
|
||||
|
||||
if stype == 'SURFACE':
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[0,:]))
|
||||
fid.writelines("%f " % ii for ii in mkvc(tx[0,:]))
|
||||
M = M[:,0]
|
||||
N = N[:,0]
|
||||
|
||||
if stype == 'GENERAL':
|
||||
|
||||
# Flip sign for z-elevation to depth
|
||||
tx[2::2,:] = -tx[2::2,:]
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[::2,:]))
|
||||
M = M[:,0::2]
|
||||
N = N[:,0::2]
|
||||
|
||||
# Flip sign for z-elevation to depth
|
||||
M[:,1::2] = -M[:,1::2]
|
||||
N[:,1::2] = -N[:,1::2]
|
||||
|
||||
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='%f',delimiter=' ',newline='\n')
|
||||
|
||||
if dtype=='3D':
|
||||
|
||||
@@ -529,11 +554,12 @@ def writeUBC_DCobs(fileName, DCsurvey, dtype, stype):
|
||||
|
||||
if stype == 'GENERAL':
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx))
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[0:3,:]))
|
||||
|
||||
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')
|
||||
|
||||
fid.write('\n')
|
||||
|
||||
count += nD
|
||||
|
||||
fid.close()
|
||||
@@ -640,51 +666,59 @@ def convertObs_DC3D_to_2D(DCsurvey,lineID, flag = 'local'):
|
||||
DCsurvey2D.std = np.asarray(DCsurvey.std)
|
||||
|
||||
return DCsurvey2D
|
||||
|
||||
def readUBC_DC3Dobs(fileName):
|
||||
|
||||
def readUBC_DC3Dobs(fileName, dtype = 'DC'):
|
||||
"""
|
||||
Read UBC GIF DCIP 3D observation file and generate survey
|
||||
Read UBC GIF IP 3D observation file and generate survey
|
||||
|
||||
Input:
|
||||
:param fileName, path to the UBC GIF 3D obs file
|
||||
|
||||
Output:
|
||||
:param DCIPsurvey
|
||||
:param IPsurvey
|
||||
:return
|
||||
|
||||
Created on Mon April 6th, 2015
|
||||
|
||||
@author: dominiquef
|
||||
|
||||
"""
|
||||
|
||||
zflag = True # Flag for z value provided
|
||||
|
||||
# Load file
|
||||
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!')
|
||||
|
||||
if dtype == 'IP':
|
||||
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='IPTYPE')
|
||||
|
||||
elif dtype == 'DC':
|
||||
obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!')
|
||||
|
||||
else:
|
||||
print "dtype must be 'DC'(default) | 'IP'"
|
||||
|
||||
# Pre-allocate
|
||||
srcLists = []
|
||||
Rx = []
|
||||
d = []
|
||||
wd = []
|
||||
zflag = True # Flag for z value provided
|
||||
|
||||
|
||||
# Countdown for number of obs/tx
|
||||
count = 0
|
||||
for ii in range(obsfile.shape[0]):
|
||||
|
||||
# Skip if blank line
|
||||
if not obsfile[ii]:
|
||||
continue
|
||||
|
||||
# First line is transmitter with number of receivers
|
||||
# First line or end of a transmitter block, read transmitter info
|
||||
if count==0:
|
||||
|
||||
temp = (np.fromstring(obsfile[ii], dtype=float,sep=' ').T)
|
||||
# Read the line
|
||||
temp = (np.fromstring(obsfile[ii], dtype=float, sep=' ').T)
|
||||
count = int(temp[-1])
|
||||
|
||||
# Check if z value is provided, if False -> nan
|
||||
if len(temp)==5:
|
||||
tx = np.r_[temp[0:2],np.nan,temp[0:2],np.nan]
|
||||
zflag = False
|
||||
tx = np.r_[temp[0:2],np.nan,temp[2:4],np.nan]
|
||||
|
||||
zflag = False # Pass on the flag to the receiver loc
|
||||
|
||||
else:
|
||||
tx = temp[:-1]
|
||||
@@ -692,8 +726,16 @@ def readUBC_DC3Dobs(fileName):
|
||||
rx = []
|
||||
continue
|
||||
|
||||
temp = np.fromstring(obsfile[ii], dtype=float,sep=' ')
|
||||
temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') # Get the string
|
||||
|
||||
# Filter out negative IP
|
||||
# if temp[-2] < 0:
|
||||
# count = count -1
|
||||
# print "Negative!"
|
||||
#
|
||||
# else:
|
||||
|
||||
# If the Z-location is provided, otherwise put nan
|
||||
if zflag:
|
||||
|
||||
rx.append(temp[:-2])
|
||||
@@ -703,7 +745,7 @@ def readUBC_DC3Dobs(fileName):
|
||||
wd.append(temp[-1])
|
||||
|
||||
else:
|
||||
rx.append(np.r_[temp[0:2],np.nan,temp[0:2],np.nan] )
|
||||
rx.append(np.r_[temp[0:2],np.nan,temp[2:4],np.nan] )
|
||||
# Check if there is data with the location
|
||||
if len(temp)==6:
|
||||
d.append(temp[-2])
|
||||
@@ -711,7 +753,7 @@ def readUBC_DC3Dobs(fileName):
|
||||
|
||||
count = count -1
|
||||
|
||||
# Reach the end of transmitter block
|
||||
# Reach the end of transmitter block, append the src, rx and continue
|
||||
if count == 0:
|
||||
rx = np.asarray(rx)
|
||||
Rx = DC.RxDipole(rx[:,:3],rx[:,3:])
|
||||
|
||||
+47
-44
@@ -146,10 +146,15 @@ class BetaSchedule(InversionDirective):
|
||||
|
||||
class TargetMisfit(InversionDirective):
|
||||
|
||||
chifact = 1.
|
||||
phi_d_star = None
|
||||
|
||||
@property
|
||||
def target(self):
|
||||
if getattr(self, '_target', None) is None:
|
||||
self._target = self.survey.nD*0.5
|
||||
if self.phi_d_star is None:
|
||||
self.phi_d_star = 0.5 * self.survey.nD
|
||||
self._target = self.chifact * self.phi_d_star # the factor of 0.5 is because we do phid = 0.5*|| dpred - dobs||^2
|
||||
return self._target
|
||||
@target.setter
|
||||
def target(self, val):
|
||||
@@ -222,7 +227,7 @@ class SaveOutputDictEveryIteration(_SaveEveryIteration):
|
||||
mref = 0
|
||||
mx = self.reg.Wx * ( self.reg.mapping * (self.invProb.curModel - mref) )
|
||||
phi_mx = 0.5 * mx.dot(mx)
|
||||
if self.prob.mesh.dim==2:
|
||||
if self.prob.mesh.dim >= 2:
|
||||
my = self.reg.Wy * ( self.reg.mapping * (self.invProb.curModel - mref) )
|
||||
phi_my = 0.5 * my.dot(my)
|
||||
else:
|
||||
@@ -237,41 +242,6 @@ class SaveOutputDictEveryIteration(_SaveEveryIteration):
|
||||
# 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)
|
||||
|
||||
#==============================================================================
|
||||
# class SaveOutputDictEveryIteration(_SaveEveryIteration):
|
||||
# """SaveOutputDictEveryIteration
|
||||
# A directive that saves some relevant information from the inversion run to a numpy .npz dictionary file (see numpy.savez function for further info).
|
||||
# """
|
||||
#
|
||||
# def initialize(self):
|
||||
# print "SimPEG.SaveOutputDictEveryIteration will save your inversion progress as dictionary: '%s-###.npz'"%self.fileName
|
||||
#
|
||||
# def endIter(self):
|
||||
# # Save the data.
|
||||
# ms = self.reg.Ws * ( self.reg.mapping * (self.invProb.curModel - self.reg.mref) )
|
||||
# phi_ms = 0.5*ms.dot(ms)
|
||||
# if self.reg.mrefInSmooth == True:
|
||||
# mref = self.reg.mref
|
||||
# else:
|
||||
# mref = 0
|
||||
# mx = self.reg.Wx * ( self.reg.mapping * (self.invProb.curModel - mref) )
|
||||
# phi_mx = 0.5 * mx.dot(mx)
|
||||
# if self.prob.mesh.dim==2:
|
||||
# my = self.reg.Wy * ( self.reg.mapping * (self.invProb.curModel - mref) )
|
||||
# phi_my = 0.5 * my.dot(my)
|
||||
# else:
|
||||
# phi_my = 'NaN'
|
||||
# if self.prob.mesh.dim==3 and 'CYL' not in self.prob.mesh._meshType:
|
||||
# mz = self.reg.Wz * ( self.reg.mapping * (self.invProb.curModel - mref) )
|
||||
# phi_mz = 0.5 * mz.dot(mz)
|
||||
# else:
|
||||
# phi_mz = 'NaN'
|
||||
#
|
||||
#
|
||||
# # Save the file as a npz
|
||||
# np.savez('{:s}-{:03d}'.format(self.fileName,self.opt.iter), 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):
|
||||
|
||||
@@ -293,6 +263,7 @@ class Update_IRLS(InversionDirective):
|
||||
phi_m_last = None
|
||||
phi_d_last = None
|
||||
|
||||
|
||||
def initialize(self):
|
||||
|
||||
# Scale the regularization for changes in norm
|
||||
@@ -310,7 +281,7 @@ class Update_IRLS(InversionDirective):
|
||||
self.phi_d_last = self.invProb.phi_d
|
||||
|
||||
def endIter(self):
|
||||
# Cool the threshold parameter
|
||||
# Cool the threshold parameter if required
|
||||
if getattr(self, 'factor', None) is not None:
|
||||
eps = self.reg.eps / self.factor
|
||||
|
||||
@@ -325,28 +296,44 @@ class Update_IRLS(InversionDirective):
|
||||
# Update the model used for the IRLS weights
|
||||
self.reg.curModel = self.invProb.curModel
|
||||
|
||||
# Temporarely set gamma to 1.
|
||||
# Temporarely set gamma to 1. to get raw phi_m
|
||||
self.reg.gamma = 1.
|
||||
|
||||
# Compute change in model objective function and update scaling
|
||||
# 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
|
||||
|
||||
self.invProb.beta = self.invProb.beta * self.survey.nD*0.5 / self.invProb.phi_d
|
||||
# Set the weighting matrix to None so that it is recomputed next time
|
||||
# it is called in the inversion
|
||||
self.reg._W = None
|
||||
|
||||
class Update_lin_PreCond(InversionDirective):
|
||||
"""
|
||||
Create a Jacobi preconditioner for the linear problem
|
||||
"""
|
||||
onlyOnStart=False
|
||||
|
||||
def initialize(self):
|
||||
|
||||
if getattr(self.opt, 'approxHinv', None) is None:
|
||||
# Update the pre-conditioner
|
||||
diagA = np.sum(self.prob.G**2.,axis=0) + self.invProb.beta*(self.reg.W.T*self.reg.W).diagonal() #* (self.reg.mapping * np.ones(self.reg.curModel.size))**2.
|
||||
PC = Utils.sdiag((self.prob.mapping.deriv(None).T *diagA)**-1.)
|
||||
self.opt.approxHinv = PC
|
||||
|
||||
def endIter(self):
|
||||
# Cool the threshold parameter
|
||||
if self.onlyOnStart==True:
|
||||
return
|
||||
|
||||
if getattr(self.opt, 'approxHinv', None) is not None:
|
||||
# Update the pre-conditioner
|
||||
diagA = np.sum(self.prob.G**2.,axis=0) + self.invProb.beta*(self.reg.W.T*self.reg.W).diagonal() * (self.reg.mapping * np.ones(self.reg.curModel.size))**2.
|
||||
PC = Utils.sdiag(diagA**-1.)
|
||||
diagA = np.sum(self.prob.G**2.,axis=0) + self.invProb.beta*(self.reg.W.T*self.reg.W).diagonal() #* (self.reg.mapping * np.ones(self.reg.curModel.size))**2.
|
||||
PC = Utils.sdiag((self.prob.mapping.deriv(None).T *diagA)**-1.)
|
||||
self.opt.approxHinv = PC
|
||||
print 'Updated pre-cond'
|
||||
|
||||
|
||||
class Update_Wj(InversionDirective):
|
||||
"""
|
||||
@@ -373,3 +360,19 @@ class Update_Wj(InversionDirective):
|
||||
JtJdiag = JtJdiag / max(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
|
||||
|
||||
+27
-28
@@ -2,20 +2,20 @@ import numpy as np
|
||||
from scipy.constants import mu_0, pi
|
||||
from scipy import special
|
||||
|
||||
def DCAnalyticHalf(txloc, rxlocs, sigma, flag="wholespace"):
|
||||
def DCAnalyticHalf(txloc, rxlocs, sigma, earth_type="wholespace"):
|
||||
"""
|
||||
Analytic solution for electric potential from a postive pole
|
||||
|
||||
Input variables:
|
||||
|
||||
txloc = a xyz location of A (+) electrode (np.r_[xa, ya, za])
|
||||
:param array txloc: a xyz location of A (+) electrode (np.r_[xa, ya, za])
|
||||
:param list rxlocs: xyz locations of M (+) and N (-) electrodes [M, N]
|
||||
|
||||
e.g.
|
||||
rxlocs = [M, N]
|
||||
M: xyz locations of M (+) electrode (np.c_[xmlocs, ymlocs, zmlocs])
|
||||
N: xyz locations of N (-) electrode (np.c_[xnlocs, ynlocs, znlocs])
|
||||
M: xyz locations of M (+) electrode (np.c_[xmlocs, ymlocs, zmlocs])
|
||||
N: xyz locations of N (-) electrode (np.c_[xnlocs, ynlocs, znlocs])
|
||||
|
||||
sigma = conductivity (either float or complex)
|
||||
flag = "wholsespace" or "halfspace"
|
||||
:param float or complex sigma: values of conductivity
|
||||
:param string earth_type: values of conductivity ("wholsespace" or "halfspace")
|
||||
|
||||
"""
|
||||
M = rxlocs[0]
|
||||
@@ -28,7 +28,7 @@ def DCAnalyticHalf(txloc, rxlocs, sigma, flag="wholespace"):
|
||||
phiN = 1./(4*np.pi*rN*sigma)
|
||||
phi = phiM - phiN
|
||||
|
||||
if flag == "halfspace":
|
||||
if earth_type == "halfspace":
|
||||
phi *= 2
|
||||
|
||||
return phi
|
||||
@@ -37,27 +37,26 @@ deg2rad = lambda deg: deg/180.*np.pi
|
||||
rad2deg = lambda rad: rad*180./np.pi
|
||||
|
||||
def DCAnalyticSphere(txloc, rxloc, xc, radius, sigma, sigma1, \
|
||||
flag = "sec", order=12, halfspace=False):
|
||||
field_type = "secondary", order=12, halfspace=False):
|
||||
# def DCSpherePointCurrent(txloc, rxloc, xc, radius, rho, rho1, \
|
||||
# flag = "sec", order=12):
|
||||
# field_type = "secondary", order=12):
|
||||
"""
|
||||
|
||||
Parameters:
|
||||
|
||||
txloc (array) : current electrode location (x,y,z)
|
||||
xc (float) : x center of depressed sphere
|
||||
rxloc (array) : electrode locations
|
||||
(Nx3 array, # of electrodes)
|
||||
radius (float): radius of the sphere (m)
|
||||
rho (float) : resistivity of the background (ohm-m)
|
||||
rho1 (float) : resistivity of the sphere
|
||||
flag (string) : "sec", "total", "prim"
|
||||
(default="sec")
|
||||
"sec": secondary potential only due to sphere
|
||||
"prim": primary potential from the point source
|
||||
"total": "sec"+"prim"
|
||||
order (float) : maximum order of Legendre polynomial
|
||||
(default=12)
|
||||
:param array txloc: A (+) current electrode location (x,y,z)
|
||||
:param array xc: x center of depressed sphere
|
||||
:param array rxloc: M(+) electrode locations / (Nx3 array, # of electrodes)
|
||||
|
||||
:param float radius: radius (float): radius of the sphere (m)
|
||||
:param float rho: resistivity of the background (ohm-m)
|
||||
:param float rho1: resistivity of the sphere
|
||||
:param string field_type: : "secondary", "total", "primary"
|
||||
(default="secondary")
|
||||
"secondary": secondary potential only due to sphere
|
||||
"primary": primary potential from the point source
|
||||
"total": "secondary"+"primary"
|
||||
:param float order: maximum order of Legendre polynomial (default=12)
|
||||
|
||||
Written by Seogi Kang (skang@eos.ubc.ca)
|
||||
Ph.D. Candidate of University of British Columbia, Canada
|
||||
@@ -86,7 +85,7 @@ def DCAnalyticSphere(txloc, rxloc, xc, radius, sigma, sigma1, \
|
||||
# primary potential in a whole space
|
||||
prim = rho*1./(4*np.pi*R)
|
||||
|
||||
if flag =="prim":
|
||||
if field_type =="primary":
|
||||
return prim
|
||||
|
||||
sphind = r < radius
|
||||
@@ -105,9 +104,9 @@ def DCAnalyticSphere(txloc, rxloc, xc, radius, sigma, sigma1, \
|
||||
else:
|
||||
scale = 1
|
||||
|
||||
if flag == "sec":
|
||||
if field_type == "secondary":
|
||||
return scale*(out-prim)
|
||||
elif flag == "total":
|
||||
elif field_type == "total":
|
||||
return scale*out
|
||||
|
||||
def AnBnfun(n, radius, x0, rho, rho1, I=1.):
|
||||
|
||||
+18
-1
@@ -62,6 +62,15 @@ class BaseEMProblem(Problem.BaseProblem):
|
||||
self._Me = self.mesh.getEdgeInnerProduct()
|
||||
return self._Me
|
||||
|
||||
@property
|
||||
def MeI(self):
|
||||
"""
|
||||
Edge inner product matrix
|
||||
"""
|
||||
if getattr(self, '_MeI', None) is None:
|
||||
self._MeI = self.mesh.getEdgeInnerProduct(invMat=True)
|
||||
return self._MeI
|
||||
|
||||
@property
|
||||
def Mf(self):
|
||||
"""
|
||||
@@ -71,13 +80,21 @@ class BaseEMProblem(Problem.BaseProblem):
|
||||
self._Mf = self.mesh.getFaceInnerProduct()
|
||||
return self._Mf
|
||||
|
||||
@property
|
||||
def MfI(self):
|
||||
"""
|
||||
Face inner product matrix
|
||||
"""
|
||||
if getattr(self, '_MfI', None) is None:
|
||||
self._MfI = self.mesh.getFaceInnerProduct(invMat=True)
|
||||
return self._MfI
|
||||
|
||||
@property
|
||||
def Vol(self):
|
||||
if getattr(self, '_Vol', None) is None:
|
||||
self._Vol = Utils.sdiag(self.mesh.vol)
|
||||
return self._Vol
|
||||
|
||||
|
||||
# ----- Magnetic Permeability ----- #
|
||||
@property
|
||||
def MfMui(self):
|
||||
|
||||
@@ -160,9 +160,9 @@ class Fields(SimPEG.Problem.Fields):
|
||||
return self._jDeriv_u(src, v, adjoint), self._jDeriv_m(src, v, adjoint)
|
||||
return np.array(self._jDeriv_u(src, du_dm_v, adjoint) + self._jDeriv_m(src, v, adjoint), dtype = complex)
|
||||
|
||||
class Fields_e(Fields):
|
||||
class Fields3D_e(Fields):
|
||||
"""
|
||||
Fields object for Problem_e.
|
||||
Fields object for Problem3D_e.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
@@ -426,9 +426,9 @@ class Fields_e(Fields):
|
||||
|
||||
|
||||
|
||||
class Fields_b(Fields):
|
||||
class Fields3D_b(Fields):
|
||||
"""
|
||||
Fields object for Problem_b.
|
||||
Fields object for Problem3D_b.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
@@ -693,9 +693,9 @@ class Fields_b(Fields):
|
||||
return Zero()
|
||||
|
||||
|
||||
class Fields_j(Fields):
|
||||
class Fields3D_j(Fields):
|
||||
"""
|
||||
Fields object for Problem_j.
|
||||
Fields object for Problem3D_j.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
@@ -988,9 +988,9 @@ class Fields_j(Fields):
|
||||
return 1./(1j * omega(src.freq)) * VI * (self._aveE2CCV * ( s_mDeriv(v) - self._edgeCurl.T * ( self._MfRhoDeriv(jSolution) * v ) ) )
|
||||
|
||||
|
||||
class Fields_h(Fields):
|
||||
class Fields3D_h(Fields):
|
||||
"""
|
||||
Fields object for Problem_h.
|
||||
Fields object for Problem3D_h.
|
||||
|
||||
:param Mesh mesh: mesh
|
||||
:param Survey survey: survey
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from SimPEG import Problem, Utils, np, sp, Solver as SimpegSolver
|
||||
from scipy.constants import mu_0
|
||||
from SurveyFDEM import Survey as SurveyFDEM
|
||||
from FieldsFDEM import Fields, Fields_e, Fields_b, Fields_h, Fields_j
|
||||
from FieldsFDEM import Fields, Fields3D_e, Fields3D_b, Fields3D_h, Fields3D_j
|
||||
from SimPEG.EM.Base import BaseEMProblem
|
||||
from SimPEG.EM.Utils import omega
|
||||
|
||||
@@ -17,8 +17,8 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
\mathbf{C} \mathbf{e} + i \omega \mathbf{b} = \mathbf{s_m} \\\\
|
||||
{\mathbf{C}^{\\top} \mathbf{M_{\mu^{-1}}^f} \mathbf{b} - \mathbf{M_{\sigma}^e} \mathbf{e} = \mathbf{s_e}}
|
||||
|
||||
if using the E-B formulation (:code:`Problem_e`
|
||||
or :code:`Problem_b`). Note that in this case, :math:`\mathbf{s_e}` is an integrated quantity.
|
||||
if using the E-B formulation (:code:`Problem3D_e`
|
||||
or :code:`Problem3D_b`). Note that in this case, :math:`\mathbf{s_e}` is an integrated quantity.
|
||||
|
||||
If we write Maxwell's equations in terms of
|
||||
\\\(\\\mathbf{h}\\\) and current density \\\(\\\mathbf{j}\\\)
|
||||
@@ -28,7 +28,7 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{j} + i \omega \mathbf{M_{\mu}^e} \mathbf{h} = \mathbf{s_m} \\\\
|
||||
\mathbf{C} \mathbf{h} - \mathbf{j} = \mathbf{s_e}
|
||||
|
||||
if using the H-J formulation (:code:`Problem_j` or :code:`Problem_h`). Note that here, :math:`\mathbf{s_m}` is an integrated quantity.
|
||||
if using the H-J formulation (:code:`Problem3D_j` or :code:`Problem3D_h`). Note that here, :math:`\mathbf{s_m}` is an integrated quantity.
|
||||
|
||||
The problem performs the elimination so that we are solving the system for \\\(\\\mathbf{e},\\\mathbf{b},\\\mathbf{j} \\\) or \\\(\\\mathbf{h}\\\)
|
||||
"""
|
||||
@@ -87,7 +87,7 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
du_dm_v = Ainv * ( - dA_dm_v + dRHS_dm_v )
|
||||
|
||||
for rx in src.rxList:
|
||||
df_dmFun = getattr(f, '_%sDeriv'%rx.projField, None)
|
||||
df_dmFun = getattr(f, '_{0}Deriv'.format(rx.projField), None)
|
||||
df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
|
||||
Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
||||
Ainv.clean()
|
||||
@@ -125,7 +125,7 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
for rx in src.rxList:
|
||||
PTv = rx.evalDeriv(src, self.mesh, f, v[src, rx], adjoint=True) # wrt f, need possibility wrt m
|
||||
|
||||
df_duTFun = getattr(f, '_%sDeriv'%rx.projField, None)
|
||||
df_duTFun = getattr(f, '_{0}Deriv'.format(rx.projField), None)
|
||||
df_duT, df_dmT = df_duTFun(src, None, PTv, adjoint=True)
|
||||
|
||||
ATinvdf_duT = ATinv * df_duT
|
||||
@@ -137,10 +137,9 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
df_dmT = df_dmT + du_dmT
|
||||
|
||||
# TODO: this should be taken care of by the reciever?
|
||||
real_or_imag = rx.projComp
|
||||
if real_or_imag is 'real':
|
||||
if rx.component is 'real':
|
||||
Jtv += np.array(df_dmT, dtype=complex).real
|
||||
elif real_or_imag is 'imag':
|
||||
elif rx.component is 'imag':
|
||||
Jtv += - np.array(df_dmT, dtype=complex).real
|
||||
else:
|
||||
raise Exception('Must be real or imag')
|
||||
@@ -178,7 +177,7 @@ class BaseFDEMProblem(BaseEMProblem):
|
||||
################################ E-B Formulation #########################################
|
||||
##########################################################################################
|
||||
|
||||
class Problem_e(BaseFDEMProblem):
|
||||
class Problem3D_e(BaseFDEMProblem):
|
||||
"""
|
||||
By eliminating the magnetic flux density using
|
||||
|
||||
@@ -200,7 +199,7 @@ class Problem_e(BaseFDEMProblem):
|
||||
|
||||
_solutionType = 'eSolution'
|
||||
_formulation = 'EB'
|
||||
fieldsPair = Fields_e
|
||||
fieldsPair = Fields3D_e
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
BaseFDEMProblem.__init__(self, mesh, **kwargs)
|
||||
@@ -289,7 +288,7 @@ class Problem_e(BaseFDEMProblem):
|
||||
return C.T * (MfMui * s_mDeriv(v)) -1j * omega(freq) * s_eDeriv(v)
|
||||
|
||||
|
||||
class Problem_b(BaseFDEMProblem):
|
||||
class Problem3D_b(BaseFDEMProblem):
|
||||
"""
|
||||
We eliminate :math:`\mathbf{e}` using
|
||||
|
||||
@@ -311,7 +310,7 @@ class Problem_b(BaseFDEMProblem):
|
||||
|
||||
_solutionType = 'bSolution'
|
||||
_formulation = 'EB'
|
||||
fieldsPair = Fields_b
|
||||
fieldsPair = Fields3D_b
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
BaseFDEMProblem.__init__(self, mesh, **kwargs)
|
||||
@@ -437,7 +436,7 @@ class Problem_b(BaseFDEMProblem):
|
||||
##########################################################################################
|
||||
|
||||
|
||||
class Problem_j(BaseFDEMProblem):
|
||||
class Problem3D_j(BaseFDEMProblem):
|
||||
"""
|
||||
We eliminate \\\(\\\mathbf{h}\\\) using
|
||||
|
||||
@@ -459,7 +458,7 @@ class Problem_j(BaseFDEMProblem):
|
||||
|
||||
_solutionType = 'jSolution'
|
||||
_formulation = 'HJ'
|
||||
fieldsPair = Fields_j
|
||||
fieldsPair = Fields3D_j
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
BaseFDEMProblem.__init__(self, mesh, **kwargs)
|
||||
@@ -578,7 +577,7 @@ class Problem_j(BaseFDEMProblem):
|
||||
|
||||
|
||||
|
||||
class Problem_h(BaseFDEMProblem):
|
||||
class Problem3D_h(BaseFDEMProblem):
|
||||
"""
|
||||
We eliminate \\\(\\\mathbf{j}\\\) using
|
||||
|
||||
@@ -597,7 +596,7 @@ class Problem_h(BaseFDEMProblem):
|
||||
|
||||
_solutionType = 'hSolution'
|
||||
_formulation = 'HJ'
|
||||
fieldsPair = Fields_h
|
||||
fieldsPair = Fields3D_h
|
||||
|
||||
def __init__(self, mesh, **kwargs):
|
||||
BaseFDEMProblem.__init__(self, mesh, **kwargs)
|
||||
@@ -0,0 +1,126 @@
|
||||
import SimPEG
|
||||
from SimPEG import sp
|
||||
|
||||
class BaseRx(SimPEG.Survey.BaseRx):
|
||||
"""
|
||||
Frequency domain receiver base class
|
||||
|
||||
: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):
|
||||
assert(orientation in ['x','y','z']), "Orientation %s not known. Orientation must be in 'x', 'y', 'z'. Arbitrary orientations have not yet been implemented."%orientation
|
||||
assert(component in ['real', 'imag']), "'component' must be 'real' or 'imag', not %s"%component
|
||||
|
||||
self.projComp = orientation
|
||||
self.component = component
|
||||
|
||||
SimPEG.Survey.BaseRx.__init__(self, locs, rxType=None) #TODO: remove rxType from baseRx
|
||||
|
||||
def projGLoc(self, u):
|
||||
"""Grid Location projection (e.g. Ex Fy ...)"""
|
||||
return u._GLoc(self.projField) + self.projComp
|
||||
|
||||
def eval(self, src, mesh, f):
|
||||
"""
|
||||
Project fields to recievers to get data.
|
||||
|
||||
:param Source src: FDEM source
|
||||
:param Mesh mesh: mesh used
|
||||
:param Fields f: fields object
|
||||
:rtype: numpy.ndarray
|
||||
:return: fields projected to recievers
|
||||
"""
|
||||
|
||||
P = self.getP(mesh, self.projGLoc(f))
|
||||
f_part_complex = f[src, self.projField]
|
||||
f_part = getattr(f_part_complex, self.component) # get the real or imag component
|
||||
|
||||
return P*f_part
|
||||
|
||||
def evalDeriv(self, src, mesh, f, v, adjoint=False):
|
||||
"""
|
||||
Derivative of projected fields with respect to the inversion model times a vector.
|
||||
|
||||
:param Source src: FDEM source
|
||||
:param Mesh mesh: mesh used
|
||||
:param Fields f: fields object
|
||||
:param numpy.ndarray v: vector to multiply
|
||||
:rtype: numpy.ndarray
|
||||
:return: fields projected to recievers
|
||||
"""
|
||||
|
||||
P = self.getP(mesh, self.projGLoc(f))
|
||||
|
||||
if not adjoint:
|
||||
Pv_complex = P * v
|
||||
Pv = getattr(Pv_complex, self.component)
|
||||
elif adjoint:
|
||||
Pv_real = P.T * v
|
||||
|
||||
if self.component == 'imag':
|
||||
Pv = 1j*Pv_real
|
||||
elif self.component == 'real':
|
||||
Pv = Pv_real.astype(complex)
|
||||
else:
|
||||
raise NotImplementedError('must be real or imag')
|
||||
|
||||
return Pv
|
||||
|
||||
|
||||
class Point_e(BaseRx):
|
||||
"""
|
||||
Electric field 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 = 'e'
|
||||
super(Point_e, self).__init__(locs, orientation, component)
|
||||
|
||||
|
||||
class Point_b(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 = 'b'
|
||||
super(Point_b, self).__init__(locs, orientation, component)
|
||||
|
||||
|
||||
class Point_h(BaseRx):
|
||||
"""
|
||||
Magnetic field 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 = 'h'
|
||||
super(Point_h, self).__init__(locs, orientation, component)
|
||||
|
||||
|
||||
class Point_j(BaseRx):
|
||||
"""
|
||||
Current density 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 = 'j'
|
||||
super(Point_j, self).__init__(locs, orientation, component)
|
||||
+31
-21
@@ -9,8 +9,14 @@ class BaseSrc(Survey.BaseSrc):
|
||||
"""
|
||||
|
||||
freq = None
|
||||
# rxPair = RxFDEM
|
||||
integrate = True
|
||||
integrate = False
|
||||
_ePrimary = None
|
||||
_bPrimary = None
|
||||
_hPrimary = None
|
||||
_jPrimary = None
|
||||
|
||||
def __init__(self, rxList, **kwargs):
|
||||
Survey.BaseSrc.__init__(self, rxList, **kwargs)
|
||||
|
||||
def eval(self, prob):
|
||||
"""
|
||||
@@ -50,7 +56,9 @@ class BaseSrc(Survey.BaseSrc):
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary magnetic flux density
|
||||
"""
|
||||
return Zero()
|
||||
if self._bPrimary is None:
|
||||
return Zero()
|
||||
return self._bPrimary
|
||||
|
||||
def hPrimary(self, prob):
|
||||
"""
|
||||
@@ -60,7 +68,9 @@ class BaseSrc(Survey.BaseSrc):
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary magnetic field
|
||||
"""
|
||||
return Zero()
|
||||
if self._hPrimary is None:
|
||||
return Zero()
|
||||
return self._hPrimary
|
||||
|
||||
def ePrimary(self, prob):
|
||||
"""
|
||||
@@ -70,7 +80,9 @@ class BaseSrc(Survey.BaseSrc):
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary electric field
|
||||
"""
|
||||
return Zero()
|
||||
if self._ePrimary is None:
|
||||
return Zero()
|
||||
return self._ePrimary
|
||||
|
||||
def jPrimary(self, prob):
|
||||
"""
|
||||
@@ -80,7 +92,9 @@ class BaseSrc(Survey.BaseSrc):
|
||||
:rtype: numpy.ndarray
|
||||
:return: primary current density
|
||||
"""
|
||||
return Zero()
|
||||
if self._jPrimary is None:
|
||||
return Zero()
|
||||
return self._jPrimary
|
||||
|
||||
def s_m(self, prob):
|
||||
"""
|
||||
@@ -135,15 +149,14 @@ class RawVec_e(BaseSrc):
|
||||
:param list rxList: receiver list
|
||||
:param float freq: frequency
|
||||
:param numpy.array s_e: electric source term
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [True]
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [False]
|
||||
"""
|
||||
|
||||
def __init__(self, rxList, freq, s_e, integrate=True): #, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None):
|
||||
def __init__(self, rxList, freq, s_e, **kwargs):
|
||||
self._s_e = np.array(s_e, dtype=complex)
|
||||
self.freq = float(freq)
|
||||
self.integrate = integrate
|
||||
|
||||
BaseSrc.__init__(self, rxList)
|
||||
BaseSrc.__init__(self, rxList, **kwargs)
|
||||
|
||||
def s_e(self, prob):
|
||||
"""
|
||||
@@ -165,15 +178,14 @@ class RawVec_m(BaseSrc):
|
||||
:param float freq: frequency
|
||||
:param rxList: receiver list
|
||||
:param numpy.array s_m: magnetic source term
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [True]
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [False]
|
||||
"""
|
||||
|
||||
def __init__(self, rxList, freq, s_m, integrate=True): #ePrimary=Zero(), bPrimary=Zero(), hPrimary=Zero(), jPrimary=Zero()):
|
||||
def __init__(self, rxList, freq, s_m, **kwargs): #ePrimary=Zero(), bPrimary=Zero(), hPrimary=Zero(), jPrimary=Zero()):
|
||||
self._s_m = np.array(s_m, dtype=complex)
|
||||
self.freq = float(freq)
|
||||
self.integrate = integrate
|
||||
|
||||
BaseSrc.__init__(self, rxList)
|
||||
BaseSrc.__init__(self, rxList, **kwargs)
|
||||
|
||||
def s_m(self, prob):
|
||||
"""
|
||||
@@ -196,14 +208,13 @@ class RawVec(BaseSrc):
|
||||
:param float freq: frequency
|
||||
:param numpy.array s_m: magnetic source term
|
||||
:param numpy.array s_e: electric source term
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [True]
|
||||
:param bool integrate: Integrate the source term (multiply by Me) [False]
|
||||
"""
|
||||
def __init__(self, rxList, freq, s_m, s_e, integrate=True):
|
||||
def __init__(self, rxList, freq, s_m, s_e, **kwargs):
|
||||
self._s_m = np.array(s_m, dtype=complex)
|
||||
self._s_e = np.array(s_e, dtype=complex)
|
||||
self.freq = float(freq)
|
||||
self.integrate = integrate
|
||||
BaseSrc.__init__(self, rxList)
|
||||
BaseSrc.__init__(self, rxList, **kwargs)
|
||||
|
||||
def s_m(self, prob):
|
||||
"""
|
||||
@@ -277,14 +288,13 @@ class MagDipole(BaseSrc):
|
||||
:param float mu: background magnetic permeability
|
||||
"""
|
||||
|
||||
def __init__(self, rxList, freq, loc, orientation='Z', moment=1., mu=mu_0):
|
||||
def __init__(self, rxList, freq, loc, orientation='Z', moment=1., mu=mu_0, **kwargs):
|
||||
self.freq = float(freq)
|
||||
self.loc = loc
|
||||
self.orientation = orientation
|
||||
assert orientation in ['X','Y','Z'], "Orientation (right now) doesn't actually do anything! The methods in SrcUtils should take care of this..."
|
||||
self.moment = moment
|
||||
self.mu = mu
|
||||
self.integrate = False
|
||||
BaseSrc.__init__(self, rxList)
|
||||
|
||||
def bPrimary(self, prob):
|
||||
@@ -542,7 +552,7 @@ class CircularLoop(BaseSrc):
|
||||
if not prob.mesh.isSymmetric:
|
||||
# TODO ?
|
||||
raise NotImplementedError('Non-symmetric cyl mesh not implemented yet!')
|
||||
a = MagneticDipoleVectorPotential(self.loc, gridY, 'y', moment=self.radius, mu=self.mu)
|
||||
a = MagneticLoopVectorPotential(self.loc, gridY, 'y', moment=self.radius, mu=self.mu)
|
||||
|
||||
else:
|
||||
srcfct = MagneticDipoleVectorPotential
|
||||
|
||||
@@ -4,126 +4,9 @@ from SimPEG.EM.Base import BaseEMSurvey
|
||||
from scipy.constants import mu_0
|
||||
from SimPEG.Utils import Zero, Identity
|
||||
import SrcFDEM as Src
|
||||
import RxFDEM as Rx
|
||||
from SimPEG import sp
|
||||
|
||||
|
||||
####################################################
|
||||
# Receivers
|
||||
####################################################
|
||||
|
||||
class Rx(SimPEG.Survey.BaseRx):
|
||||
"""
|
||||
Frequency domain receivers
|
||||
|
||||
:param numpy.ndarray locs: receiver locations (ie. :code:`np.r_[x,y,z]`)
|
||||
:param string rxType: reciever type from knownRxTypes
|
||||
"""
|
||||
|
||||
knownRxTypes = {
|
||||
'exr':['e', 'x', 'real'],
|
||||
'eyr':['e', 'y', 'real'],
|
||||
'ezr':['e', 'z', 'real'],
|
||||
'exi':['e', 'x', 'imag'],
|
||||
'eyi':['e', 'y', 'imag'],
|
||||
'ezi':['e', 'z', 'imag'],
|
||||
|
||||
'bxr':['b', 'x', 'real'],
|
||||
'byr':['b', 'y', 'real'],
|
||||
'bzr':['b', 'z', 'real'],
|
||||
'bxi':['b', 'x', 'imag'],
|
||||
'byi':['b', 'y', 'imag'],
|
||||
'bzi':['b', 'z', 'imag'],
|
||||
|
||||
'jxr':['j', 'x', 'real'],
|
||||
'jyr':['j', 'y', 'real'],
|
||||
'jzr':['j', 'z', 'real'],
|
||||
'jxi':['j', 'x', 'imag'],
|
||||
'jyi':['j', 'y', 'imag'],
|
||||
'jzi':['j', 'z', 'imag'],
|
||||
|
||||
'hxr':['h', 'x', 'real'],
|
||||
'hyr':['h', 'y', 'real'],
|
||||
'hzr':['h', 'z', 'real'],
|
||||
'hxi':['h', 'x', 'imag'],
|
||||
'hyi':['h', 'y', 'imag'],
|
||||
'hzi':['h', 'z', 'imag'],
|
||||
}
|
||||
radius = None
|
||||
|
||||
def __init__(self, locs, rxType):
|
||||
SimPEG.Survey.BaseRx.__init__(self, locs, rxType)
|
||||
|
||||
@property
|
||||
def projField(self):
|
||||
"""Field Type projection (e.g. e b ...)"""
|
||||
return self.knownRxTypes[self.rxType][0]
|
||||
|
||||
@property
|
||||
def projComp(self):
|
||||
"""Component projection (real/imag)"""
|
||||
return self.knownRxTypes[self.rxType][2]
|
||||
|
||||
def projGLoc(self, f):
|
||||
"""Grid Location projection (e.g. Ex Fy ...)"""
|
||||
return f._GLoc(self.rxType[0]) + self.knownRxTypes[self.rxType][1]
|
||||
|
||||
def eval(self, src, mesh, f):
|
||||
"""
|
||||
Project fields to recievers to get data.
|
||||
|
||||
:param Source src: FDEM source
|
||||
:param Mesh mesh: mesh used
|
||||
:param Fields f: fields object
|
||||
:rtype: numpy.ndarray
|
||||
:return: fields projected to recievers
|
||||
"""
|
||||
# projGLoc = u._GLoc(self.knownRxTypes[self.rxType][0])
|
||||
# projGLoc += self.knownRxTypes[self.rxType][1]
|
||||
|
||||
P = self.getP(mesh, self.projGLoc(f))
|
||||
f_part_complex = f[src, self.projField]
|
||||
# get the real or imag component
|
||||
real_or_imag = self.projComp
|
||||
f_part = getattr(f_part_complex, real_or_imag)
|
||||
|
||||
return P*f_part
|
||||
|
||||
def evalDeriv(self, src, mesh, f, v, adjoint=False):
|
||||
"""
|
||||
Derivative of projected fields with respect to the inversion model times a vector.
|
||||
|
||||
:param Source src: FDEM source
|
||||
:param Mesh mesh: mesh used
|
||||
:param Fields f: fields object
|
||||
:param numpy.ndarray v: vector to multiply
|
||||
:rtype: numpy.ndarray
|
||||
:return: fields projected to recievers
|
||||
"""
|
||||
|
||||
P = self.getP(mesh, self.projGLoc(f))
|
||||
|
||||
if not adjoint:
|
||||
Pv_complex = P * v
|
||||
real_or_imag = self.projComp
|
||||
Pv = getattr(Pv_complex, real_or_imag)
|
||||
elif adjoint:
|
||||
Pv_real = P.T * v
|
||||
|
||||
real_or_imag = self.projComp
|
||||
if real_or_imag == 'imag':
|
||||
Pv = 1j*Pv_real
|
||||
elif real_or_imag == 'real':
|
||||
Pv = Pv_real.astype(complex)
|
||||
else:
|
||||
raise NotImplementedError('must be real or imag')
|
||||
|
||||
return Pv
|
||||
|
||||
|
||||
####################################################
|
||||
# Survey
|
||||
####################################################
|
||||
|
||||
class Survey(BaseEMSurvey):
|
||||
"""
|
||||
Frequency domain electromagnetic survey
|
||||
@@ -132,7 +15,7 @@ class Survey(BaseEMSurvey):
|
||||
"""
|
||||
|
||||
srcPair = Src.BaseSrc
|
||||
rxPair = Rx
|
||||
rxPair = Rx.BaseRx
|
||||
|
||||
def __init__(self, srcList, **kwargs):
|
||||
# Sort these by frequency
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from SurveyFDEM import Rx, Src, Survey
|
||||
from FDEM import BaseFDEMProblem, Problem_e, Problem_b, Problem_j, Problem_h
|
||||
from FieldsFDEM import *
|
||||
from SurveyFDEM import Survey
|
||||
import SrcFDEM as Src
|
||||
import RxFDEM as Rx
|
||||
from ProblemFDEM import Problem3D_e, Problem3D_b, Problem3D_j, Problem3D_h
|
||||
from FieldsFDEM import Fields3D_e, Fields3D_b, Fields3D_j, Fields3D_h
|
||||
|
||||
@@ -35,10 +35,11 @@ class BaseDCProblem(BaseEMProblem):
|
||||
|
||||
self.curModel = m
|
||||
|
||||
Jv = self.dataPair(self.survey) #same size as the data
|
||||
|
||||
# Jv = self.dataPair(self.survey) #same size as the data
|
||||
A = self.getA()
|
||||
|
||||
Jv = []
|
||||
|
||||
for src in self.survey.srcList:
|
||||
u_src = f[src, self._solutionType] # solution vector
|
||||
dA_dm_v = self.getADeriv(u_src, v)
|
||||
@@ -48,8 +49,10 @@ class BaseDCProblem(BaseEMProblem):
|
||||
for rx in src.rxList:
|
||||
df_dmFun = getattr(f, '_%sDeriv'%rx.projField, None)
|
||||
df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
|
||||
Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
||||
return Utils.mkvc(Jv)
|
||||
# Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
||||
Jv.append(rx.evalDeriv(src, self.mesh, f, df_dm_v))
|
||||
# return Utils.mkvc(Jv)
|
||||
return np.hstack(Jv)
|
||||
|
||||
def Jtvec(self, m, v, f=None):
|
||||
if f is None:
|
||||
@@ -64,7 +67,6 @@ class BaseDCProblem(BaseEMProblem):
|
||||
Jtv = np.zeros(m.size)
|
||||
AT = self.getA()
|
||||
|
||||
|
||||
for src in self.survey.srcList:
|
||||
u_src = f[src, self._solutionType]
|
||||
for rx in src.rxList:
|
||||
@@ -122,13 +124,12 @@ class Problem3D_CC(BaseDCProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = D MfRhoI G
|
||||
|
||||
"""
|
||||
|
||||
D = self.Div
|
||||
G = self.Grad
|
||||
# TODO: this won't work for full anisotropy
|
||||
MfRhoI = self.MfRhoI
|
||||
A = D * MfRhoI * G
|
||||
|
||||
@@ -144,13 +145,8 @@ class Problem3D_CC(BaseDCProblem):
|
||||
MfRhoIDeriv = self.MfRhoIDeriv
|
||||
|
||||
if adjoint:
|
||||
# if self._makeASymmetric is True:
|
||||
# v = V * v
|
||||
return(MfRhoIDeriv( G * u ).T) * ( D.T * v)
|
||||
|
||||
# I think we should deprecate this for DC problem.
|
||||
# if self._makeASymmetric is True:
|
||||
# return V.T * ( D * ( MfRhoIDeriv( D.T * ( V * u ) ) * v ) )
|
||||
return D * (MfRhoIDeriv( G * u ) * v)
|
||||
|
||||
def getRHS(self):
|
||||
@@ -162,10 +158,6 @@ class Problem3D_CC(BaseDCProblem):
|
||||
|
||||
RHS = self.getSourceTerm()
|
||||
|
||||
# I think we should deprecate this for DC problem.
|
||||
# if self._makeASymmetric is True:
|
||||
# return self.Vol.T * RHS
|
||||
|
||||
return RHS
|
||||
|
||||
def getRHSDeriv(self, src, v, adjoint=False):
|
||||
@@ -255,11 +247,10 @@ class Problem3D_N(BaseDCProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = G.T MeSigma G
|
||||
|
||||
"""
|
||||
|
||||
# TODO: this won't work for full anisotropy
|
||||
MeSigma = self.MeSigma
|
||||
Grad = self.mesh.nodalGrad
|
||||
A = Grad.T * MeSigma * Grad
|
||||
|
||||
@@ -161,14 +161,13 @@ class Problem2D_CC(BaseDCProblem_2D):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = D MfRhoI G
|
||||
|
||||
"""
|
||||
|
||||
D = self.Div
|
||||
G = self.Grad
|
||||
vol = self.mesh.vol
|
||||
# TODO: this won't work for full anisotropy
|
||||
MfRhoI = self.MfRhoI
|
||||
# Get resistivity rho
|
||||
rho = self.curModel.rho
|
||||
@@ -304,11 +303,10 @@ class Problem2D_N(BaseDCProblem_2D):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = D MfRhoI G
|
||||
|
||||
"""
|
||||
|
||||
# TODO: this won't work for full anisotropy
|
||||
MeSigma = self.MeSigma
|
||||
MnSigma = self.MnSigma
|
||||
Grad = self.mesh.nodalGrad
|
||||
|
||||
@@ -45,7 +45,8 @@ class BaseIPProblem(BaseEMProblem):
|
||||
|
||||
self.curModel = m
|
||||
|
||||
Jv = self.dataPair(self.survey) #same size as the data
|
||||
# Jv = self.dataPair(self.survey) #same size as the data
|
||||
Jv = []
|
||||
|
||||
A = self.getA()
|
||||
|
||||
@@ -58,13 +59,16 @@ class BaseIPProblem(BaseEMProblem):
|
||||
for rx in src.rxList:
|
||||
df_dmFun = getattr(f, '_%sDeriv'%rx.projField, None)
|
||||
df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
|
||||
Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
||||
# Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
|
||||
Jv.append(rx.evalDeriv(src, self.mesh, f, df_dm_v))
|
||||
# Conductivity (d u / d log sigma)
|
||||
if self._formulation is 'EB':
|
||||
return -Utils.mkvc(Jv)
|
||||
# return -Utils.mkvc(Jv)
|
||||
return -np.hstack(Jv)
|
||||
# Conductivity (d u / d log rho)
|
||||
if self._formulation is 'HJ':
|
||||
return Utils.mkvc(Jv)
|
||||
# return Utils.mkvc(Jv)
|
||||
return np.hstack(Jv)
|
||||
|
||||
def Jtvec(self, m, v, f=None):
|
||||
if f is None:
|
||||
@@ -180,13 +184,12 @@ class Problem3D_CC(BaseIPProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = D MfRhoI G
|
||||
|
||||
"""
|
||||
|
||||
D = self.Div
|
||||
G = self.Grad
|
||||
# TODO: this won't work for full anisotropy
|
||||
MfRhoI = self.MfRhoI
|
||||
A = D * MfRhoI * G
|
||||
|
||||
@@ -313,11 +316,10 @@ class Problem3D_N(BaseIPProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = G.T MeSigma G
|
||||
|
||||
"""
|
||||
|
||||
# TODO: this won't work for full anisotropy
|
||||
MeSigma = self.MeSigma
|
||||
Grad = self.mesh.nodalGrad
|
||||
A = Grad.T * MeSigma * Grad
|
||||
|
||||
@@ -251,7 +251,7 @@ class Problem3D_CC(BaseSIPProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = D MfRhoI G
|
||||
|
||||
"""
|
||||
|
||||
@@ -384,7 +384,7 @@ class Problem3D_N(BaseSIPProblem):
|
||||
|
||||
Make the A matrix for the cell centered DC resistivity problem
|
||||
|
||||
A = D MfRhoI D^\\top V
|
||||
A = G.T MeSigma G
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@@ -315,3 +315,107 @@ def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
|
||||
|
||||
return SrcList
|
||||
|
||||
|
||||
def writeUBC_DCobs(fileName, DCsurvey, dtype='3D', stype='SURFACE', iptype = 0):
|
||||
"""
|
||||
Write UBC GIF DCIP 2D or 3D observation file
|
||||
|
||||
Input:
|
||||
:string fileName -> including path where the file is written out
|
||||
:DCsurvey DC survey class object
|
||||
:string dtype -> either '2D' | '3D'
|
||||
:string stype -> either 'SURFACE' | 'GENERAL'
|
||||
|
||||
Output:
|
||||
:param UBC2D-Data file
|
||||
:return
|
||||
|
||||
Last edit: February 16th, 2016
|
||||
|
||||
@author: dominiquef
|
||||
|
||||
"""
|
||||
from SimPEG import mkvc
|
||||
|
||||
assert (dtype=='2D') | (dtype=='3D'), "Data must be either '2D' | '3D'"
|
||||
assert (stype=='SURFACE') | (stype=='GENERAL') | (stype=='SIMPLE'), "Data must be either 'SURFACE' | 'GENERAL' | 'SIMPLE'"
|
||||
|
||||
fid = open(fileName,'w')
|
||||
|
||||
|
||||
if iptype!=0:
|
||||
fid.write('IPTYPE=%i\n'%iptype)
|
||||
|
||||
else:
|
||||
fid.write('! ' + stype + ' FORMAT\n')
|
||||
|
||||
count = 0
|
||||
|
||||
for ii in range(DCsurvey.nSrc):
|
||||
|
||||
tx = np.c_[DCsurvey.srcList[ii].loc]
|
||||
|
||||
rx = DCsurvey.srcList[ii].rxList[0].locs
|
||||
|
||||
nD = DCsurvey.srcList[ii].nD
|
||||
|
||||
M = rx[0]
|
||||
N = rx[1]
|
||||
|
||||
# Adapt source-receiver location for dtype and stype
|
||||
if dtype=='2D':
|
||||
|
||||
if stype == 'SIMPLE':
|
||||
|
||||
#fid.writelines("%e " % ii for ii in mkvc(tx[0,:]))
|
||||
A = np.repeat(tx[0,0],M.shape[0],axis=0)
|
||||
B = np.repeat(tx[0,1],M.shape[0],axis=0)
|
||||
M = M[:,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')
|
||||
|
||||
|
||||
else:
|
||||
|
||||
if stype == 'SURFACE':
|
||||
|
||||
fid.writelines("%f " % ii for ii in mkvc(tx[0,:]))
|
||||
M = M[:,0]
|
||||
N = N[:,0]
|
||||
|
||||
if stype == 'GENERAL':
|
||||
|
||||
# Flip sign for z-elevation to depth
|
||||
tx[2::2,:] = -tx[2::2,:]
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[::2,:]))
|
||||
M = M[:,0::2]
|
||||
N = N[:,0::2]
|
||||
|
||||
# Flip sign for z-elevation to depth
|
||||
M[:,1::2] = -M[:,1::2]
|
||||
N[:,1::2] = -N[:,1::2]
|
||||
|
||||
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')
|
||||
|
||||
if dtype=='3D':
|
||||
|
||||
if stype == 'SURFACE':
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[0:2,:]))
|
||||
M = M[:,0:2]
|
||||
N = N[:,0:2]
|
||||
|
||||
if stype == 'GENERAL':
|
||||
|
||||
fid.writelines("%e " % ii for ii in mkvc(tx[0:3,:]))
|
||||
|
||||
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')
|
||||
fid.write('\n')
|
||||
|
||||
count += nD
|
||||
|
||||
fid.close()
|
||||
|
||||
@@ -20,56 +20,61 @@ def getFDEMProblem(fdemType, comp, SrcList, freq, useMu=False, verbose=False):
|
||||
mesh = Mesh.TensorMesh([hx,hy,hz],['C','C','C'])
|
||||
|
||||
if useMu is True:
|
||||
mapping = [('sigma', Maps.ExpMap(mesh)), ('mu', Maps.IdentityMap(mesh))]
|
||||
mapping = [('sigma', Maps.ExpMap(mesh)), ('mu', Maps.IdentityMap(mesh))]
|
||||
else:
|
||||
mapping = Maps.ExpMap(mesh)
|
||||
|
||||
x = np.array([np.linspace(-5.*cs,-2.*cs,3),np.linspace(5.*cs,2.*cs,3)]) + cs/4. #don't sample right by the source, slightly off alignment from either staggered grid
|
||||
XYZ = Utils.ndgrid(x,x,np.linspace(-2.*cs,2.*cs,5))
|
||||
Rx0 = EM.FDEM.Rx(XYZ, comp)
|
||||
Rx0 = getattr(EM.FDEM.Rx, 'Point_' + comp[0])
|
||||
if comp[2] == 'r':
|
||||
real_or_imag = 'real'
|
||||
elif comp[2] == 'i':
|
||||
real_or_imag = 'imag'
|
||||
rx0 = Rx0(XYZ, comp[1], 'imag')
|
||||
|
||||
Src = []
|
||||
|
||||
for SrcType in SrcList:
|
||||
if SrcType is 'MagDipole':
|
||||
Src.append(EM.FDEM.Src.MagDipole([Rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
Src.append(EM.FDEM.Src.MagDipole([rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
elif SrcType is 'MagDipole_Bfield':
|
||||
Src.append(EM.FDEM.Src.MagDipole_Bfield([Rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
Src.append(EM.FDEM.Src.MagDipole_Bfield([rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
elif SrcType is 'CircularLoop':
|
||||
Src.append(EM.FDEM.Src.CircularLoop([Rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
Src.append(EM.FDEM.Src.CircularLoop([rx0], freq=freq, loc=np.r_[0.,0.,0.]))
|
||||
elif SrcType is 'RawVec':
|
||||
if fdemType is 'e' or fdemType is 'b':
|
||||
S_m = np.zeros(mesh.nF)
|
||||
S_e = np.zeros(mesh.nE)
|
||||
S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1e-3
|
||||
S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1e-3
|
||||
Src.append(EM.FDEM.Src.RawVec([Rx0], freq, S_m, S_e))
|
||||
Src.append(EM.FDEM.Src.RawVec([rx0], freq, S_m, mesh.getEdgeInnerProduct()*S_e))
|
||||
|
||||
elif fdemType is 'h' or fdemType is 'j':
|
||||
S_m = np.zeros(mesh.nE)
|
||||
S_e = np.zeros(mesh.nF)
|
||||
S_m[Utils.closestPoints(mesh,[0.,0.,0.],'Ez') + np.sum(mesh.vnE[:1])] = 1e-3
|
||||
S_e[Utils.closestPoints(mesh,[0.,0.,0.],'Fz') + np.sum(mesh.vnF[:1])] = 1e-3
|
||||
Src.append(EM.FDEM.Src.RawVec([Rx0], freq, S_m, S_e))
|
||||
Src.append(EM.FDEM.Src.RawVec([rx0], freq, mesh.getEdgeInnerProduct()*S_m, S_e))
|
||||
|
||||
if verbose:
|
||||
print ' Fetching %s problem' % (fdemType)
|
||||
|
||||
if fdemType == 'e':
|
||||
survey = EM.FDEM.Survey(Src)
|
||||
prb = EM.FDEM.Problem_e(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_e(mesh, mapping=mapping)
|
||||
|
||||
elif fdemType == 'b':
|
||||
survey = EM.FDEM.Survey(Src)
|
||||
prb = EM.FDEM.Problem_b(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping)
|
||||
|
||||
elif fdemType == 'j':
|
||||
survey = EM.FDEM.Survey(Src)
|
||||
prb = EM.FDEM.Problem_j(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_j(mesh, mapping=mapping)
|
||||
|
||||
elif fdemType == 'h':
|
||||
survey = EM.FDEM.Survey(Src)
|
||||
prb = EM.FDEM.Problem_h(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_h(mesh, mapping=mapping)
|
||||
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
@@ -90,7 +95,7 @@ def crossCheckTest(SrcList, fdemType1, fdemType2, comp, addrandoms = False, useM
|
||||
prb1 = getFDEMProblem(fdemType1, comp, SrcList, freq, useMu, verbose)
|
||||
mesh = prb1.mesh
|
||||
print 'Cross Checking Forward: %s, %s formulations - %s' % (fdemType1, fdemType2, comp)
|
||||
|
||||
|
||||
logsig = np.log(np.ones(mesh.nC)*CONDUCTIVITY)
|
||||
mu = np.ones(mesh.nC)*MU
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ def run(plotIt=True):
|
||||
ax.grid(color='k', alpha=0.5, linestyle='dashed', linewidth=0.5)
|
||||
|
||||
|
||||
rxOffset=10.
|
||||
bzi = EM.FDEM.Rx(np.array([[rxOffset, 0., 1e-3]]), 'bzi')
|
||||
rxOffset=10.
|
||||
bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., 1e-3]]), orientation='z', component='imag')
|
||||
|
||||
freqs = np.logspace(1,3,10)
|
||||
srcLoc = np.array([0., 0., 10.])
|
||||
@@ -51,7 +51,7 @@ def run(plotIt=True):
|
||||
srcList = [EM.FDEM.Src.MagDipole([bzi],freq, srcLoc,orientation='Z') for freq in freqs]
|
||||
|
||||
survey = EM.FDEM.Survey(srcList)
|
||||
prb = EM.FDEM.Problem_b(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping)
|
||||
|
||||
try:
|
||||
from pymatsolver import MumpsSolver
|
||||
|
||||
@@ -215,7 +215,7 @@ def run(plotIt=True):
|
||||
# ------------ Problem and Survey ---------------
|
||||
survey = FDEM.Survey(sg_p + dg_p)
|
||||
mapping = [('sigma', Maps.IdentityMap(mesh))]
|
||||
problem = FDEM.Problem_h(mesh, mapping=mapping)
|
||||
problem = FDEM.Problem3D_h(mesh, mapping=mapping)
|
||||
problem.pair(survey)
|
||||
|
||||
# ------------- Solve ---------------------------
|
||||
|
||||
@@ -86,12 +86,12 @@ def run(N=200, plotIt=True):
|
||||
#reg.recModel = mrec
|
||||
reg.wght = np.ones(mesh.nC)
|
||||
reg.mref = np.zeros(mesh.nC)
|
||||
reg.eps_p = 2e-3
|
||||
reg.eps_q = 2e-3
|
||||
reg.eps_p = 5e-2
|
||||
reg.eps_q = 1e-2
|
||||
reg.norms = [0., 0., 2., 2.]
|
||||
reg.wght = wr
|
||||
|
||||
opt = Optimization.ProjectedGNCG(maxIter=5 ,lower=-2.,upper=2., maxIterCG= 100, tolCG = 1e-3)
|
||||
opt = Optimization.ProjectedGNCG(maxIter=10 ,lower=-2.,upper=2., maxIterLS = 20, maxIterCG= 20, tolCG = 1e-3)
|
||||
invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta = invProb.beta*2.)
|
||||
beta = Directives.BetaSchedule(coolingFactor=1, coolingRate=1)
|
||||
#betaest = Directives.BetaEstimate_ByEig()
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
from SimPEG import SolverLU as SimpegSolver, PropMaps, Utils, mkvc, sp, np
|
||||
from SimPEG.EM.FDEM.FDEM import BaseFDEMProblem
|
||||
from SimPEG.EM.FDEM.ProblemFDEM import BaseFDEMProblem
|
||||
from SurveyMT import Survey, Data
|
||||
from FieldsMT import BaseMTFields
|
||||
|
||||
|
||||
@@ -7,17 +7,16 @@ from SimPEG.MT.Utils.dataUtils import rec2ndarr
|
||||
# Import modules
|
||||
import numpy as np
|
||||
import os, sys, re
|
||||
try:
|
||||
import osr
|
||||
except ImportError as e:
|
||||
print 'Could not import osr, missing the gdal package'
|
||||
pass
|
||||
|
||||
|
||||
class EDIimporter:
|
||||
"""
|
||||
A class to import EDIfiles.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
# Define data converters
|
||||
_impUnitEDI2SI = 4*np.pi*1e-4 # Convert Z[mV/km/nT] (as in EDI)to Z[V/A] SI unit
|
||||
_impUnitSI2EDI = 1./_impUnitEDI2SI # ConvertZ[V/A] SI unit to Z[mV/km/nT] (as in EDI)
|
||||
|
||||
@@ -26,8 +25,8 @@ class EDIimporter:
|
||||
comps = None
|
||||
|
||||
# Hidden properties
|
||||
_outEPSG = None
|
||||
_2out = None
|
||||
_outEPSG = None # Project info
|
||||
_2out = None # The projection operator
|
||||
|
||||
|
||||
def __init__(self, EDIfilesList, compList=None, outEPSG=None):
|
||||
@@ -113,6 +112,12 @@ class EDIimporter:
|
||||
# nOutData=length(obj.data);
|
||||
# obj.data(nOutData+1:nOutData+length(TEMP.data),:) = TEMP.data;
|
||||
def _transfromPoints(self,longD,latD):
|
||||
# Import the coordinate projections
|
||||
try:
|
||||
import osr
|
||||
except ImportError as e:
|
||||
print 'Could not import osr, missing the gdal package\nCan not project coordinates'
|
||||
raise e
|
||||
# Coordinates convertor
|
||||
if self._2out is None:
|
||||
src = osr.SpatialReference()
|
||||
|
||||
+12
-9
@@ -330,7 +330,7 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView):
|
||||
raise NotImplementedError('wrapping in the averaging is not yet implemented')
|
||||
return self._aveF2CCV
|
||||
|
||||
def getInterpolationMatCartMesh(self, Mrect, locType='CC'):
|
||||
def getInterpolationMatCartMesh(self, Mrect, locType='CC', locTypeTo=None):
|
||||
"""
|
||||
Takes a cartesian mesh and returns a projection to translate onto the cartesian grid.
|
||||
"""
|
||||
@@ -338,19 +338,22 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView):
|
||||
assert self.isSymmetric, "Currently we have not taken into account other projections for more complicated CylMeshes"
|
||||
|
||||
|
||||
if locTypeTo is None:
|
||||
locTypeTo = locType
|
||||
|
||||
if locType == 'F':
|
||||
# do this three times for each component
|
||||
X = self.getInterpolationMatCartMesh(Mrect, locType='Fx')
|
||||
Y = self.getInterpolationMatCartMesh(Mrect, locType='Fy')
|
||||
Z = self.getInterpolationMatCartMesh(Mrect, locType='Fz')
|
||||
X = self.getInterpolationMatCartMesh(Mrect, locType='Fx', locTypeTo=locTypeTo+'x')
|
||||
Y = self.getInterpolationMatCartMesh(Mrect, locType='Fy', locTypeTo=locTypeTo+'y')
|
||||
Z = self.getInterpolationMatCartMesh(Mrect, locType='Fz', locTypeTo=locTypeTo+'z')
|
||||
return sp.vstack((X,Y,Z))
|
||||
if locType == 'E':
|
||||
X = self.getInterpolationMatCartMesh(Mrect, locType='Ex')
|
||||
Y = self.getInterpolationMatCartMesh(Mrect, locType='Ey')
|
||||
Z = spzeros(Mrect.nEz, self.nE)
|
||||
X = self.getInterpolationMatCartMesh(Mrect, locType='Ex', locTypeTo=locTypeTo+'x')
|
||||
Y = self.getInterpolationMatCartMesh(Mrect, locType='Ey', locTypeTo=locTypeTo+'y')
|
||||
Z = spzeros(getattr(Mrect, 'n' + locTypeTo + 'z'), self.nE)
|
||||
return sp.vstack((X,Y,Z))
|
||||
|
||||
grid = getattr(Mrect, 'grid' + locType)
|
||||
grid = getattr(Mrect, 'grid' + locTypeTo)
|
||||
# This is unit circle stuff, 0 to 2*pi, starting at x-axis, rotating counter clockwise in an x-y slice
|
||||
theta = - np.arctan2(grid[:,0] - self.cartesianOrigin[0], grid[:,1] - self.cartesianOrigin[1]) + np.pi/2
|
||||
theta[theta < 0] += np.pi*2.0
|
||||
@@ -366,7 +369,7 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView):
|
||||
'Ex': Mrect.tangents[:Mrect.nEx,:],
|
||||
'Ey': Mrect.tangents[Mrect.nEx:(Mrect.nEx+Mrect.nEy),:],
|
||||
'Ez': Mrect.tangents[-Mrect.nEz:,:],
|
||||
}[locType]
|
||||
}[locTypeTo]
|
||||
if 'F' in locType:
|
||||
normals = np.c_[np.cos(theta), np.sin(theta), np.zeros(theta.size)]
|
||||
proj = ( normals * dotMe ).sum(axis=1)
|
||||
|
||||
+23
-13
@@ -24,7 +24,6 @@ class TensorMeshIO(object):
|
||||
re = int(sp[0])*(' ' + sp[1])
|
||||
line = line.replace(st,re.strip())
|
||||
return np.array(line.split(),dtype=float)
|
||||
|
||||
# Read the file as line strings, remove lines with comment = !
|
||||
msh = np.genfromtxt(fileName,delimiter='\n',dtype=np.str,comments='!')
|
||||
|
||||
@@ -206,19 +205,30 @@ class TensorMeshIO(object):
|
||||
:param simpeg.Mesh.TensorMesh mesh: The mesh
|
||||
|
||||
"""
|
||||
assert mesh.dim == 3
|
||||
s = ''
|
||||
s += '%i %i %i\n' %tuple(mesh.vnC)
|
||||
origin = mesh.x0 + np.array([0,0,mesh.hz.sum()]) # Have to it in the same operation or use mesh.x0.copy(), otherwise the mesh.x0 is updated.
|
||||
origin.dtype = float
|
||||
if mesh.dim ==3:
|
||||
s = ''
|
||||
s += '%i %i %i\n' %tuple(mesh.vnC)
|
||||
origin = mesh.x0 + np.array([0,0,mesh.hz.sum()]) # Have to it in the same operation or use mesh.x0.copy(), otherwise the mesh.x0 is updated.
|
||||
origin.dtype = float
|
||||
|
||||
s += '%.2f %.2f %.2f\n' %tuple(origin)
|
||||
s += ('%.2f '*mesh.nCx+'\n')%tuple(mesh.hx)
|
||||
s += ('%.2f '*mesh.nCy+'\n')%tuple(mesh.hy)
|
||||
s += ('%.2f '*mesh.nCz+'\n')%tuple(mesh.hz[::-1])
|
||||
f = open(fileName, 'w')
|
||||
f.write(s)
|
||||
f.close()
|
||||
s += '%.2f %.2f %.2f\n' %tuple(origin)
|
||||
s += ('%.2f '*mesh.nCx+'\n')%tuple(mesh.hx)
|
||||
s += ('%.2f '*mesh.nCy+'\n')%tuple(mesh.hy)
|
||||
s += ('%.2f '*mesh.nCz+'\n')%tuple(mesh.hz[::-1])
|
||||
f = open(fileName, 'w')
|
||||
f.write(s)
|
||||
f.close()
|
||||
|
||||
elif mesh.dim==2:
|
||||
fid = open(fileName,'w')
|
||||
fid.write('%i\n'% mesh.nCx)
|
||||
fid.write('%f %f 1\n'% (mesh.vectorNx[0],mesh.vectorNx[1]))
|
||||
np.savetxt(fid, np.c_[mesh.vectorNx[2:],np.ones(mesh.nCx-1)], fmt='\t %e %i',delimiter=' ',newline='\n')
|
||||
fid.write('\n')
|
||||
fid.write('%i\n'% mesh.nCy)
|
||||
fid.write('%f %f 1\n'%( 0,mesh.hy[-1]))
|
||||
np.savetxt(fid, np.c_[np.cumsum(mesh.hy[-2::-1])+mesh.hy[-1],np.ones(mesh.nCy-1)], fmt='\t %e %i',delimiter=' ',newline='\n')
|
||||
fid.close()
|
||||
|
||||
if models is None: return
|
||||
assert type(models) is dict, 'models must be a dict'
|
||||
|
||||
@@ -311,6 +311,9 @@ class BaseRegularization(object):
|
||||
tmp = indActive
|
||||
indActive = np.zeros(mesh.nC, dtype=bool)
|
||||
indActive[tmp] = True
|
||||
if indActive is not None and mapping is None:
|
||||
mapping = Maps.IdentityMap(nP=indActive.nonzero()[0].size)
|
||||
|
||||
self.regmesh = RegularizationMesh(mesh,indActive)
|
||||
self.mapping = mapping or self.mapPair(mesh)
|
||||
self.mapping._assertMatchesPair(self.mapPair)
|
||||
@@ -728,14 +731,14 @@ class Sparse(Simple):
|
||||
@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 sp.vstack(wlist)
|
||||
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):
|
||||
|
||||
eta = (eps**(1-exponent/2.))**0.5
|
||||
r = eta / (f_m**2.+ eps**2.)**((1-exponent/2.)/2.)
|
||||
eta = (eps**(1.-exponent/2.))**0.5
|
||||
r = eta / (f_m**2.+ eps**2.)**((1.-exponent/2.)/2.)
|
||||
|
||||
return r
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
from SimPEG import np, Mesh
|
||||
import time as tm
|
||||
import vtk, vtk.util.numpy_support as npsup
|
||||
import re
|
||||
|
||||
def read_GOCAD_ts(tsfile):
|
||||
"""
|
||||
|
||||
Read GOCAD triangulated surface (*.ts) file
|
||||
INPUT:
|
||||
tsfile: Triangulated surface
|
||||
|
||||
OUTPUT:
|
||||
vrts : Array of vertices in XYZ coordinates [n x 3]
|
||||
trgl : Array of index for triangles [m x 3]. The order of the vertices
|
||||
is important and describes the normal
|
||||
n = cross( (P2 - P1 ) , (P3 - P1) )
|
||||
|
||||
Author: @fourndo
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Remove all attributes from the GoCAD surface before exporting it!
|
||||
|
||||
"""
|
||||
|
||||
|
||||
fid = open(tsfile,'r')
|
||||
line = fid.readline()
|
||||
|
||||
# Skip all the lines until the vertices
|
||||
while re.match('TFACE',line)==None:
|
||||
line = fid.readline()
|
||||
|
||||
line = fid.readline()
|
||||
vrtx = []
|
||||
|
||||
# Run down all the vertices and save in array
|
||||
while re.match('VRTX',line):
|
||||
l_input = re.split('[\s*]',line)
|
||||
temp = np.array(l_input[2:5])
|
||||
vrtx.append(temp.astype(np.float))
|
||||
|
||||
# Read next line
|
||||
line = fid.readline()
|
||||
|
||||
vrtx = np.asarray(vrtx)
|
||||
|
||||
# Skip lines to the triangles
|
||||
while re.match('TRGL',line)==None:
|
||||
line = fid.readline()
|
||||
|
||||
# Run down the list of triangles
|
||||
trgl = []
|
||||
|
||||
# Run down all the vertices and save in array
|
||||
while re.match('TRGL',line):
|
||||
l_input = re.split('[\s*]',line)
|
||||
temp = np.array(l_input[1:4])
|
||||
trgl.append(temp.astype(np.int))
|
||||
|
||||
# Read next line
|
||||
line = fid.readline()
|
||||
|
||||
trgl = np.asarray(trgl)
|
||||
|
||||
return vrtx, trgl
|
||||
|
||||
def surface2inds(vrtx, trgl, mesh, boundaries=True, internal=True):
|
||||
""""
|
||||
Function to read gocad polystructure file and output indexes of mesh with in the structure.
|
||||
|
||||
"""
|
||||
# Adjust the index
|
||||
trgl = trgl - 1
|
||||
|
||||
# Make vtk pts
|
||||
ptsvtk = vtk.vtkPoints()
|
||||
ptsvtk.SetData(npsup.numpy_to_vtk(vrtx,deep=1))
|
||||
|
||||
# Make the polygon connection
|
||||
polys = vtk.vtkCellArray()
|
||||
for face in trgl:
|
||||
poly = vtk.vtkPolygon()
|
||||
poly.GetPointIds().SetNumberOfIds(len(face))
|
||||
for nrv, vert in enumerate(face):
|
||||
poly.GetPointIds().SetId(nrv,vert)
|
||||
polys.InsertNextCell(poly)
|
||||
|
||||
# Make the polydata, structure of connections and vrtx
|
||||
polyData = vtk.vtkPolyData()
|
||||
polyData.SetPoints(ptsvtk)
|
||||
polyData.SetPolys(polys)
|
||||
|
||||
# Make implicit func
|
||||
ImpDistFunc = vtk.vtkImplicitPolyDataDistance()
|
||||
ImpDistFunc.SetInput(polyData)
|
||||
|
||||
# Convert the mesh
|
||||
vtkMesh = vtk.vtkRectilinearGrid()
|
||||
vtkMesh.SetDimensions(mesh.nNx,mesh.nNy,mesh.nNz)
|
||||
vtkMesh.SetXCoordinates(npsup.numpy_to_vtk(mesh.vectorNx, deep=1))
|
||||
vtkMesh.SetYCoordinates(npsup.numpy_to_vtk(mesh.vectorNy, deep=1))
|
||||
vtkMesh.SetZCoordinates(npsup.numpy_to_vtk(mesh.vectorNz, deep=1))
|
||||
# Add indexes
|
||||
vtkInd = npsup.numpy_to_vtk(np.arange(mesh.nC), deep=1)
|
||||
vtkInd.SetName('Index')
|
||||
vtkMesh.GetCellData().AddArray(vtkInd)
|
||||
|
||||
extractImpDistRectGridFilt = vtk.vtkExtractGeometry() # Object constructor
|
||||
extractImpDistRectGridFilt.SetImplicitFunction(ImpDistFunc) #
|
||||
extractImpDistRectGridFilt.SetInputData(vtkMesh)
|
||||
|
||||
if boundaries is True:
|
||||
extractImpDistRectGridFilt.ExtractBoundaryCellsOn()
|
||||
|
||||
else:
|
||||
extractImpDistRectGridFilt.ExtractBoundaryCellsOff()
|
||||
|
||||
if internal is True:
|
||||
extractImpDistRectGridFilt.ExtractInsideOn()
|
||||
|
||||
else:
|
||||
extractImpDistRectGridFilt.ExtractInsideOff()
|
||||
|
||||
print "Extracting indices from grid..."
|
||||
# Executing the pipe
|
||||
extractImpDistRectGridFilt.Update()
|
||||
|
||||
# Get index inside
|
||||
insideGrid = extractImpDistRectGridFilt.GetOutput()
|
||||
insideGrid = npsup.vtk_to_numpy(insideGrid.GetCellData().GetArray('Index'))
|
||||
|
||||
|
||||
# Return the indexes inside
|
||||
return insideGrid
|
||||
@@ -22,7 +22,7 @@ radi = Radius of spheres [r1,r2]
|
||||
param = Conductivity of background and two spheres [m0,m1,m2]
|
||||
stype = survey type "pdp" (pole dipole) or "dpdp" (dipole dipole)
|
||||
dtype = Data type "appr" (app res) | "appc" (app cond) | "volt" (potential)
|
||||
Created by @fourndo on Mon Feb 01 19:28:06 2016
|
||||
Created by @fourndo
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,16 +5,17 @@ SimPEG is a python package for simulation and gradient based
|
||||
parameter estimation in the context of geophysical applications.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils.command.build_ext import build_ext
|
||||
from setuptools import find_packages
|
||||
from distutils.extension import Extension
|
||||
|
||||
|
||||
|
||||
CLASSIFIERS = [
|
||||
'Development Status :: 4 - Beta',
|
||||
'Intended Audience :: Developers',
|
||||
@@ -51,11 +52,16 @@ if args.count("build_ext") > 0 and args.count("--inplace") == 0:
|
||||
try:
|
||||
from Cython.Build import cythonize
|
||||
from Cython.Distutils import build_ext
|
||||
cythonKwargs = dict(cmdclass={'build_ext': build_ext})
|
||||
USE_CYTHON = True
|
||||
except Exception, e:
|
||||
USE_CYTHON = False
|
||||
cythonKwargs = dict()
|
||||
|
||||
class NumpyBuild(build_ext):
|
||||
def finalize_options(self):
|
||||
build_ext.finalize_options(self)
|
||||
__builtins__.__NUMPY_SETUP__ = False
|
||||
import numpy
|
||||
self.include_dirs.append(numpy.get_include())
|
||||
|
||||
ext = '.pyx' if USE_CYTHON else '.c'
|
||||
|
||||
@@ -94,8 +100,8 @@ setup(
|
||||
classifiers=CLASSIFIERS,
|
||||
platforms = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"],
|
||||
use_2to3 = False,
|
||||
include_dirs=[np.get_include()],
|
||||
cmdclass={'build_ext':NumpyBuild},
|
||||
setup_requires=['numpy'],
|
||||
ext_modules = extensions,
|
||||
scripts=scripts,
|
||||
**cythonKwargs
|
||||
)
|
||||
|
||||
@@ -65,10 +65,8 @@ class RegularizationTests(unittest.TestCase):
|
||||
elif mesh.dim == 3:
|
||||
indActive = Utils.mkvc(mesh.gridCC[:,-1] <= 2*np.sin(2*np.pi*mesh.gridCC[:,0])+0.5 * 2*np.sin(2*np.pi*mesh.gridCC[:,1])+0.5)
|
||||
|
||||
mapping = Maps.IdentityMap(nP=indActive.nonzero()[0].size)
|
||||
|
||||
for indAct in [indActive, indActive.nonzero()[0]]: # test both bool and integers
|
||||
reg = r(mesh, mapping=mapping, indActive=indAct)
|
||||
reg = r(mesh, indActive=indAct)
|
||||
m = np.random.rand(mesh.nC)[indAct]
|
||||
reg.mref = np.ones_like(m)*np.mean(m)
|
||||
|
||||
|
||||
@@ -28,12 +28,12 @@ class FDEM_analyticTests(unittest.TestCase):
|
||||
|
||||
x = np.linspace(-10,10,5)
|
||||
XYZ = Utils.ndgrid(x,np.r_[0],np.r_[0])
|
||||
rxList = EM.FDEM.Rx(XYZ, 'exi')
|
||||
rxList = EM.FDEM.Rx.Point_e(XYZ, orientation='x', component='imag')
|
||||
Src0 = EM.FDEM.Src.MagDipole([rxList],loc=np.r_[0.,0.,0.], freq=freq)
|
||||
|
||||
survey = EM.FDEM.Survey([Src0])
|
||||
|
||||
prb = EM.FDEM.Problem_b(mesh, mapping=mapping)
|
||||
prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping)
|
||||
prb.pair(survey)
|
||||
|
||||
try:
|
||||
@@ -125,8 +125,8 @@ class FDEM_analyticTests(unittest.TestCase):
|
||||
|
||||
mapping = [('sigma', Maps.IdentityMap(mesh)),('mu', Maps.IdentityMap(mesh))]
|
||||
|
||||
prbe = EM.FDEM.Problem_h(mesh, mapping=mapping)
|
||||
prbm = EM.FDEM.Problem_e(mesh, mapping=mapping)
|
||||
prbe = EM.FDEM.Problem3D_h(mesh, mapping=mapping)
|
||||
prbm = EM.FDEM.Problem3D_e(mesh, mapping=mapping)
|
||||
|
||||
prbe.pair(surveye) # pair problem and survey
|
||||
prbm.pair(surveym)
|
||||
|
||||
@@ -12,7 +12,7 @@ testBH = True
|
||||
verbose = False
|
||||
|
||||
TOLEJHB = 1 # averaging and more sensitive to boundary condition violations (ie. the impact of violating the boundary conditions in each case is different.)
|
||||
#TODO: choose better testing parameters to lower this
|
||||
#TODO: choose better testing parameters to lower this
|
||||
|
||||
SrcList = ['RawVec', 'MagDipole_Bfield', 'MagDipole', 'CircularLoop']
|
||||
|
||||
@@ -125,4 +125,4 @@ class FDEM_CrossCheck(unittest.TestCase):
|
||||
self.assertTrue(crossCheckTest(SrcList, 'b', 'h', 'hzi', verbose=verbose, TOL=TOLEJHB))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
||||
@@ -18,9 +18,9 @@ class DCProblemAnalyticTests(unittest.TestCase):
|
||||
A0loc = np.r_[-150, 0.]
|
||||
A1loc = np.r_[-130, 0.]
|
||||
rxloc = [np.c_[M, np.zeros(20)], np.c_[N, np.zeros(20)]]
|
||||
data_anal = EM.Analytics.DCAnalyticHalf(np.r_[A0loc, 0.], rxloc, sighalf, flag="halfspace")
|
||||
data_anal = EM.Analytics.DCAnalyticHalf(np.r_[A0loc, 0.], rxloc, sighalf, earth_type="halfspace")
|
||||
|
||||
rx = DC.Rx.Dipole(M, N)
|
||||
rx = DC.Rx.Dipole_ky(M, N)
|
||||
src0 = DC.Src.Pole([rx], A0loc)
|
||||
survey = DC.Survey_ky([src0])
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ class DCProblemAnalyticTests(unittest.TestCase):
|
||||
Bloc = np.r_[200., 0., 0.]
|
||||
M = Utils.ndgrid(x-25.,y, np.r_[0.])
|
||||
N = Utils.ndgrid(x+25.,y, np.r_[0.])
|
||||
phiA = EM.Analytics.DCAnalyticHalf(Aloc, [M,N], 1e-2, flag="halfspace")
|
||||
phiB = EM.Analytics.DCAnalyticHalf(Bloc, [M,N], 1e-2, flag="halfspace")
|
||||
phiA = EM.Analytics.DCAnalyticHalf(Aloc, [M,N], 1e-2, earth_type="halfspace")
|
||||
phiB = EM.Analytics.DCAnalyticHalf(Bloc, [M,N], 1e-2, earth_type="halfspace")
|
||||
data_anal = phiA-phiB
|
||||
|
||||
rx = DC.Rx.Dipole(M, N)
|
||||
|
||||
@@ -146,6 +146,20 @@ class TestCyl2DMesh(unittest.TestCase):
|
||||
|
||||
assert np.abs(Pr*(Pc2r*mc) - Pc*mc).max() < 1e-3
|
||||
|
||||
def test_getInterpMatCartMesh_Cells2Nodes(self):
|
||||
|
||||
Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
|
||||
Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])
|
||||
|
||||
mc = np.arange(Mc.nC)
|
||||
xr = np.linspace(0,0.4,50)
|
||||
xc = np.linspace(0,0.4,50) + 0.2
|
||||
Pr = Mr.getInterpolationMat(np.c_[xr,np.ones(50)*-0.2,np.ones(50)*0.5],'N')
|
||||
Pc = Mc.getInterpolationMat(np.c_[xc,np.zeros(50),np.ones(50)*0.5],'CC')
|
||||
Pc2r = Mc.getInterpolationMatCartMesh(Mr, 'CC', locTypeTo='N')
|
||||
|
||||
assert np.abs(Pr*(Pc2r*mc) - Pc*mc).max() < 1e-3
|
||||
|
||||
def test_getInterpMatCartMesh_Faces(self):
|
||||
|
||||
Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
|
||||
@@ -177,6 +191,37 @@ class TestCyl2DMesh(unittest.TestCase):
|
||||
assert np.abs(mag[dist > 0.1].min() - 1) < TOL
|
||||
|
||||
|
||||
def test_getInterpMatCartMesh_Faces2Edges(self):
|
||||
|
||||
Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
|
||||
Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])
|
||||
|
||||
Pf2e = Mc.getInterpolationMatCartMesh(Mr, 'F', locTypeTo='E')
|
||||
mf = np.ones(Mc.nF)
|
||||
|
||||
ecart = Pf2e * mf
|
||||
|
||||
excc = Mr.aveEx2CC*Mr.r(ecart, 'E', 'Ex')
|
||||
eycc = Mr.aveEy2CC*Mr.r(ecart, 'E', 'Ey')
|
||||
ezcc = Mr.r(ecart, 'E', 'Ez')
|
||||
|
||||
indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
|
||||
indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])
|
||||
|
||||
TOL = 1e-2
|
||||
assert np.abs(float(excc[indX]) - 1) < TOL
|
||||
assert np.abs(float(excc[indY]) - 0) < TOL
|
||||
assert np.abs(float(eycc[indX]) - 0) < TOL
|
||||
assert np.abs(float(eycc[indY]) - 1) < TOL
|
||||
assert np.abs((ezcc - 1).sum()) < TOL
|
||||
|
||||
mag = (excc**2 + eycc**2)**0.5
|
||||
dist = ((Mr.gridCC[:,0] + 0.2)**2 + (Mr.gridCC[:,1] + 0.2)**2)**0.5
|
||||
|
||||
assert np.abs(mag[dist > 0.1].max() - 1) < TOL
|
||||
assert np.abs(mag[dist > 0.1].min() - 1) < TOL
|
||||
|
||||
|
||||
def test_getInterpMatCartMesh_Edges(self):
|
||||
|
||||
Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
|
||||
@@ -185,11 +230,42 @@ class TestCyl2DMesh(unittest.TestCase):
|
||||
Pe = Mc.getInterpolationMatCartMesh(Mr, 'E')
|
||||
me = np.ones(Mc.nE)
|
||||
|
||||
erect = Pe * me
|
||||
ecart = Pe * me
|
||||
|
||||
excc = Mr.aveEx2CC*Mr.r(erect, 'E', 'Ex')
|
||||
eycc = Mr.aveEy2CC*Mr.r(erect, 'E', 'Ey')
|
||||
ezcc = Mr.r(erect, 'E', 'Ez')
|
||||
excc = Mr.aveEx2CC*Mr.r(ecart, 'E', 'Ex')
|
||||
eycc = Mr.aveEy2CC*Mr.r(ecart, 'E', 'Ey')
|
||||
ezcc = Mr.aveEz2CC*Mr.r(ecart, 'E', 'Ez')
|
||||
|
||||
indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
|
||||
indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])
|
||||
|
||||
TOL = 1e-2
|
||||
assert np.abs(float(excc[indX]) - 0) < TOL
|
||||
assert np.abs(float(excc[indY]) + 1) < TOL
|
||||
assert np.abs(float(eycc[indX]) - 1) < TOL
|
||||
assert np.abs(float(eycc[indY]) - 0) < TOL
|
||||
assert np.abs(ezcc.sum()) < TOL
|
||||
|
||||
mag = (excc**2 + eycc**2)**0.5
|
||||
dist = ((Mr.gridCC[:,0] + 0.2)**2 + (Mr.gridCC[:,1] + 0.2)**2)**0.5
|
||||
|
||||
assert np.abs(mag[dist > 0.1].max() - 1) < TOL
|
||||
assert np.abs(mag[dist > 0.1].min() - 1) < TOL
|
||||
|
||||
|
||||
def test_getInterpMatCartMesh_Edges2Faces(self):
|
||||
|
||||
Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
|
||||
Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])
|
||||
|
||||
Pe2f = Mc.getInterpolationMatCartMesh(Mr, 'E', locTypeTo='F')
|
||||
me = np.ones(Mc.nE)
|
||||
|
||||
frect = Pe2f * me
|
||||
|
||||
excc = Mr.aveFx2CC*Mr.r(frect, 'F', 'Fx')
|
||||
eycc = Mr.aveFy2CC*Mr.r(frect, 'F', 'Fy')
|
||||
ezcc = Mr.r(frect, 'F', 'Fz')
|
||||
|
||||
indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
|
||||
indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])
|
||||
|
||||
@@ -242,9 +242,6 @@ class TestAnalytics(unittest.TestCase):
|
||||
def test_appRes1en3(self):self.assertTrue(appResPhsHalfspace_eFrom_ps_Norm(1e-3))
|
||||
def test_appPhs1en3(self):self.assertTrue(appResPhsHalfspace_eFrom_ps_Norm(1e-3,False))
|
||||
|
||||
# Do a derivative test
|
||||
def test_derivProj1(self):self.assertTrue(DerivProjfieldsTest(halfSpace(1e-2)))
|
||||
|
||||
# Do a derivative test of Jvec
|
||||
# def test_derivJvec_zxxr(self):self.assertTrue(DerivJvecTest(random(1e-2),'zxxr',.1))
|
||||
# def test_derivJvec_zxxi(self):self.assertTrue(DerivJvecTest(random(1e-2),'zxxi',.1))
|
||||
|
||||
Reference in New Issue
Block a user