Implement distance weighting for potential fields in BaseMag

This commit is contained in:
D Fournier
2015-12-27 11:29:01 -08:00
parent cbe3b3de42
commit 1a7656c34d
5 changed files with 8297 additions and 69 deletions
+122 -2
View File
@@ -1,6 +1,6 @@
from SimPEG import Maps, Survey, Utils, np, sp
from scipy.constants import mu_0
import re
class BaseMagSurvey(Survey.BaseSurvey):
"""Base Magnetics Survey"""
@@ -190,6 +190,7 @@ def readUBCmagObs(obs_file):
return B, M, dobs
def read_MAGfwr_inp(input_file):
"""Read input files for forward modeling MAG data with integral form
INPUT:
input_file: File name containing the forward parameter
@@ -240,4 +241,123 @@ def read_MAGfwr_inp(input_file):
else:
topofile = l_input[0].rstrip()
return mshfile, obsfile, modfile, magfile, topofile
return mshfile, obsfile, modfile, magfile, topofile
def read_MAGinv_inp(input_file):
"""Read input files for forward modeling MAG data with integral form
INPUT:
input_file: File name containing the forward parameter
OUTPUT:
mshfile
obsfile
topofile
start model
ref model
mag model
weightfile
chi_target
as, ax ,ay, az
upper, lower bounds
lp, lqx, lqy, lqz
# All files should be in the working directory, otherwise the path must
# be specified.
Created on Dec 21th, 2015
@author: dominiquef
"""
fid = open(input_file,'r')
# Line 1
line = fid.readline()
l_input = line.split('!')
mshfile = l_input[0].rstrip()
# Line 2
line = fid.readline()
l_input = line.split('!')
obsfile = l_input[0].rstrip()
# Line 3
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input=='null':
topofile = []
else:
topofile = l_input[0].rstrip()
# Line 4
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input[0]=='VALUE':
mstart = float(l_input[1])
else:
mstart = l_input[0].rstrip()
# Line 5
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input[0]=='VALUE':
mref = float(l_input[1])
else:
mref = l_input[0].rstrip()
# Line 6
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input=='DEFAULT':
magfile = []
else:
magfile = l_input[0].rstrip()
# Line 7
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input=='DEFAULT':
wgtfile = []
else:
wgtfile = l_input[0].rstrip()
# Line 8
line = fid.readline()
l_input = re.split('[!\s]',line)
chi = float(l_input[0])
# Line 9
line = fid.readline()
l_input = re.split('[!\s]',line)
val = np.array(l_input[0:4])
alphas = val.astype(np.float)
# Line 10
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input[0]=='VALUE':
val = np.array(l_input[1:3])
bounds = val.astype(np.float)
else:
bounds = l_input[0].rstrip()
# Line 11
line = fid.readline()
l_input = re.split('[!\s]',line)
if l_input[0]=='VALUE':
val = np.array(l_input[1:6])
lpnorms = val.astype(np.float)
else:
lpnorms = l_input[0].rstrip()
return mshfile, obsfile, topofile, mstart, mref, magfile, wgtfile, chi, alphas, bounds, lpnorms
+38 -9
View File
@@ -2,13 +2,15 @@ import os
home_dir = 'C:\Users\dominiquef.MIRAGEOSCIENCE\Documents\GIT\SimPEG\simpegpf\simpegPF\Dev'
inpfile = 'MAG3Cinv.inp'
inpfile = 'MAG3D_inv.inp'
dsep = '\\'
os.chdir(home_dir)
#%%
from SimPEG import np, Utils
from SimPEG import np, Utils, mkvc
import simpegPF as PF
import pylab as plt
## New scripts to be added to basecode
#from fwr_MAG_data import fwr_MAG_data
@@ -16,13 +18,10 @@ import simpegPF as PF
#%%
# Read input file
[mshfile, obsfile, modfile, magfile, topofile] = PF.BaseMag.read_MAGfwr_inp(inpfile)
[mshfile, obsfile, topofile, mstart, mref, magfile, wgtfile, chi, alphas, bounds, lpnorms] = PF.BaseMag.read_MAGinv_inp(home_dir + dsep + inpfile)
# Load mesh file
mesh = Utils.meshutils.readUBCTensorMesh(mshfile)
# Load model file
model = Utils.meshutils.readUBCTensorModel(modfile,mesh)
# Load in observation file
[B,M,dobs] = PF.BaseMag.readUBCmagObs(obsfile)
@@ -30,8 +29,38 @@ model = Utils.meshutils.readUBCTensorModel(modfile,mesh)
rxLoc = dobs[:,0:3]
ndata = rxLoc.shape[0]
# Load in topofile or create flat surface
#==============================================================================
# if topofile == 'null':
#
# Nx,Ny = np.meshgrid(mesh.vectorNx,mesh.vectorNy)
# Nz = np.ones(Nx.shape) * mesh.vectorNz[-1]
#
# topo = np.c_[mkvc(Nx),mkvc(Ny),mkvc(Nz)]
#==============================================================================
# Work with flat topogrphy for now
nullcell = np.ones(mesh.nC)
# Load model file
if isinstance(mstart, float):
mstart = np.ones(mesh.nC) * mstart
else:
mstart = Utils.meshutils.readUBCTensorModel(mstart,mesh)
# Get magnetization vector for MOF
if magfile=='DEFAULT':
M_xyz = PF.Magnetics.dipazm_2_xyz(np.ones(mesh.nC) * M[0], np.ones(mesh.nC) * M[1])
else:
M_xyz = np.genfromtxt(magfile,delimiter=' \n',dtype=np.str,comments='!')
# Create forward operator
F = PF.Magnetics.Intrgl_Fwr_Op(mesh,B,M,rxLoc,'tmi')
F = PF.Magnetics.Intrgl_Fwr_Op(mesh,B,M_xyz,rxLoc,'tmi')
# Get distance weighting function
wr = PF.Magnetics.get_dist_wgt(mesh,rxLoc,3.,np.min(mesh.hx)/4)
Utils.writeUBCTensorModel(home_dir+dsep+'wr.dat',mesh,wr)
+11
View File
@@ -0,0 +1,11 @@
Mesh.msh ! Mesh file
FWR_data.dat ! Obsfile
null ! Topofile
Model.dat ! Starting model
VALUE 0.0 ! Reference model
DEFAULT !..\AzmDip.dat ! Magnetization vector model
DEFAULT ! Cell based weight file
1 ! target chi factor | DEFAULT=1
1 1 1 1 ! alpha s, x ,y ,z
VALUE 0 1 ! Lower and Upper Bounds for p-component
VALUE 0 2 2 2 1 ! lp-norm for amplitude inversion FILE pqxqyqzr.dat ! Norms VALUE p, qx, qy, qz, r | FILE m-by-5 matrix
+8000 -27
View File
File diff suppressed because it is too large Load Diff
+126 -31
View File
@@ -527,9 +527,7 @@ def Intrgl_Fwr_Op(mesh,B,M,rxLoc,flag):
xn = mesh.vectorNx;
yn = mesh.vectorNy;
zn = mesh.vectorNz;
mcell = (len(xn)-1) * (len(yn)-1) * (len(zn)-1)
ndata = rxLoc.shape[0]
@@ -539,28 +537,20 @@ def Intrgl_Fwr_Op(mesh,B,M,rxLoc,flag):
# Pre-allocate space and create magnetization matrix if required
if (flag=='tmi') | (flag == 'xyz'):
# If assumes uniform magnetization direction
if len(M) == 3:
if M.shape != (mesh.nC,3):
print 'Magnetization vector must be 3*Ncells'
return
# Convert declination from north to cartesian
Md = (450.-float(M[1]))%360.
# Create magnetization matrix
mx = np.cos(np.deg2rad(M[0])) * np.cos(np.deg2rad(Md))
my = np.cos(np.deg2rad(M[0])) * np.sin(np.deg2rad(Md))
mz = np.sin(np.deg2rad(M[0]))
Mx = Utils.sdiag(np.ones([mcell])*mx*B[2])
My = Utils.sdiag(np.ones([mcell])*my*B[2])
Mz = Utils.sdiag(np.ones([mcell])*mz*B[2])
Mxyz = sp.vstack((Mx,My,Mz));
# Otherwise if given a vector 3*ncells
elif len(M) == mesh.nC * 3:
Mxyz = sp.spdiags(M,0,mesh.nC * 3,mesh.nC * 3)
Mx = Utils.sdiag(M[:,0]*B[2])
My = Utils.sdiag(M[:,1]*B[2])
Mz = Utils.sdiag(M[:,2]*B[2])
Mxyz = sp.vstack((Mx,My,Mz))
if flag == 'tmi':
F = np.zeros((ndata, mesh.nC))
@@ -614,7 +604,7 @@ def Intrgl_Fwr_Op(mesh,B,M,rxLoc,flag):
def get_T_mat(xn,yn,zn,rxLoc):
"""
Load in the nodes of a tensor mesh and computes the magnetic tensor
Load in the active nodes of a tensor mesh and computes the magnetic tensor
for a given observation location rxLoc[obsx, obsy, obsz]
OUTPUT:
Tx = [Txx Txy Txz]
@@ -625,6 +615,10 @@ def get_T_mat(xn,yn,zn,rxLoc):
Only the upper half 5 elements have to be computed since symetric.
Currently done as for-loops but will eventually be changed to vector
indexing, once the topography has been figured out.
Created on Oct, 20th 2015
@author: dominiquef
"""
ncx = len(xn)-1
@@ -649,18 +643,13 @@ def get_T_mat(xn,yn,zn,rxLoc):
xn2 = mkvc(xn2)
xn1 = mkvc(xn1)
#%%
#==============================================================================
dz2 = rxLoc[2] - zn1;
dz1 = rxLoc[2] - zn2;
dy2 = yn2 - rxLoc[1];
dy1 = yn1 - rxLoc[1];
dx2 = xn2 - rxLoc[0];
dx1 = xn1 - rxLoc[0];
@@ -740,7 +729,16 @@ def get_T_mat(xn,yn,zn,rxLoc):
return Tx,Ty,Tz
def progress(iter,prog,final):
"""
progress(iter,prog,final)
Function measuring the progress of a process and print to screen the %.
Useful to estimate the remaining runtime of a large problem.
Created on Dec, 20th 2015
@author: dominiquef
"""
arg = np.floor(float(iter)/float(final)*10.);
if arg > prog:
@@ -751,6 +749,103 @@ def progress(iter,prog,final):
return prog
def dipazm_2_xyz(dip,azm_N):
"""
dipazm_2_xyz(dip,azm_N)
Function converting degree angles for dip and azimuth from north to a
3-components in cartesian coordinates.
INPUT
dip : Value or vector of dip from horizontal in DEGREE
azm_N : Value or vector of azimuth from north in DEGREE
OUTPUT
M : [n-by-3] Array of xyz components of a unit vector in cartesian
Created on Dec, 20th 2015
@author: dominiquef
"""
mcell = len(azm_N)
M = np.zeros((mcell,3))
# Modify azimuth from North to Cartesian-X
azm_X = (450.- azm_N) % 360.
D = np.deg2rad(dip)
I = np.deg2rad(azm_X)
M[:,0] = np.cos(D) * np.cos(I) ;
M[:,1] = np.cos(D) * np.sin(I) ;
M[:,2] = np.sin(D) ;
return M
def get_dist_wgt(mesh,rxLoc,R,R0):
"""
get_dist_wgt(xn,yn,zn,rxLoc,R,R0)
Function creating a distance weighting function required for the magnetic
inverse problem.
INPUT
xn, yn, zn : Node location
rxLoc : Observation locations [obsx, obsy, obsz]
R : Decay factor (mag=3, grav =2)
R0 : Small factor added (default=dx/4)
OUTPUT
wr : [mcell] Vector of distance weighting
Created on Dec, 20th 2015
@author: dominiquef
"""
p = 1/np.sqrt(3);
# Create cell center location
Ym,Xm,Zm = np.meshgrid(mesh.vectorCCy, mesh.vectorCCx, mesh.vectorCCz)
hY,hX,hZ = np.meshgrid(mesh.hy, mesh.hx, mesh.hz)
V = np.reshape(mesh.vol,hY.shape)
wr = np.zeros(hY.shape)
ndata = rxLoc.shape[0]
count = -1;
print "Begin calculation of distance weighting for R= " + str(R)
for dd in range(ndata):
nx1 = (Xm - hX * p - rxLoc[dd,0])**2
nx2 = (Xm + hX * p - rxLoc[dd,0])**2
ny1 = (Ym - hY * p - rxLoc[dd,1])**2
ny2 = (Ym + hY * p - rxLoc[dd,1])**2
nz1 = (Zm - hZ * p - rxLoc[dd,2])**2
nz2 = (Zm + hZ * p - rxLoc[dd,2])**2
R1 = np.sqrt(nx1 + ny1 + nz1)
R2 = np.sqrt(nx1 + ny1 + nz2)
R3 = np.sqrt(nx2 + ny1 + nz1)
R4 = np.sqrt(nx2 + ny1 + nz2)
R5 = np.sqrt(nx1 + ny2 + nz1)
R6 = np.sqrt(nx1 + ny2 + nz2)
R7 = np.sqrt(nx2 + ny2 + nz1)
R8 = np.sqrt(nx2 + ny2 + nz2)
temp = (R1 + R0)**-R + (R2 + R0)**-R + (R3 + R0)**-R + (R4 + R0)**-R + (R5 + R0)**-R + (R6 + R0)**-R + (R7 + R0)**-R + (R8 + R0)**-R
wr = wr + (V*temp/8.)**2
count = progress(dd,count,ndata)
wr = np.sqrt(wr)/V
wr = mkvc(wr)
wr = np.sqrt(wr/(np.max(wr)))
return wr