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) ) Created on Jan 13th, 2016 Author: @fourndo """ 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 getSrc_locs(DCsurvey): """ """ srcMat = np.zeros((DCsurvey.nSrc,2,3)) for ii in range(DCsurvey.nSrc): print np.asarray(DCsurvey.srcList[ii].loc).shape srcMat[ii,:,:] = np.asarray(DCsurvey.srcList[ii].loc) return srcMat
def writeUBC_DCobs(fileName,Tx,Rx,d,wd, dtype): from SimPEG import np, mkvc import re """ Read UBC GIF DCIP 3D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 3D obs file Output: :param rx, tx, d, wd :return Created on Mon December 7th, 2015 @author: dominiquef """ fid = open(fileName,'w') fid.write('! GENERAL FORMAT\n') for ii in range(len(Tx)): tx = np.asarray(Tx[ii]) rx = np.asarray(Rx[ii]) nrx = rx.shape[0] fid.write('\n') if re.match(dtype,'2D'): for jj in range(nrx): fid.writelines("%e " % ii for ii in mkvc(tx)) fid.writelines("%e " % ii for ii in mkvc(rx[jj])) fid.write('%e %e\n'% (d[ii][jj],wd[ii][jj])) #np.savetxt(fid, np.c_[ rx ,np.asarray(d[ii]), np.asarray(wd[ii]) ], fmt='%e',delimiter=' ',newline='\n') elif re.match(dtype,'3D'): fid.write('\n') fid.writelines("%e " % ii for ii in mkvc(tx)) fid.write('%i\n'% nrx) np.savetxt(fid, np.c_[ rx ,np.asarray(d[ii]), np.asarray(wd[ii]) ], fmt='%e',delimiter=' ',newline='\n') fid.close()
def activeCells(self): if getattr(self, '_activeCells', None) is None: if getattr(self, 'topofile', None) is not None: topo = np.genfromtxt(self.basePath + self.topofile, skip_header=1) # Find the active cells active = Utils.surface2ind_topo(self.mesh, topo, 'N') elif isinstance(self._staticInput, float): active = self.m0 != self._staticInput else: # Read from file active cells with 0:air, 1:dynamic, -1 static active = self.activeModel != 0 inds = np.asarray([inds for inds, elem in enumerate(active, 1) if elem], dtype=int) - 1 self._activeCells = inds # Reduce m0 to active space self._m0 = self.m0[self._activeCells] return self._activeCells
def activeCells(self): if getattr(self, '_activeCells', None) is None: if getattr(self, 'topofile', None) is not None: topo = np.genfromtxt(self.basePath + self.topofile, skip_header=1) # Find the active cells active = Utils.surface2ind_topo(self.mesh, topo, 'N') elif isinstance(self._staticInput, float): active = self.m0 != self._staticInput else: # Read from file active cells with 0:air, 1:dynamic, -1 static active = self.activeModel != 0 inds = np.asarray( [inds for inds, elem in enumerate(active, 1) if elem], dtype=int) - 1 self._activeCells = inds # Reduce m0 to active space if len(self.m0) > len(self._activeCells): self._m0 = self.m0[self._activeCells] return self._activeCells
def makeModelFile(): """ Loads in a triangulated surface from Gocad (*.ts) and use VTK to transfer onto a 3D mesh. New scripts to be added to basecode """ #%% work_dir = '' mshfile = 'MEsh_TEst.msh' # Load mesh file mesh = Mesh.TensorMesh.readUBC(work_dir+mshfile) # Load in observation file #[B,M,dobs] = PF.BaseMag.readUBCmagObs(obsfile) # Read in topo surface topsurf = work_dir+'CDED_Lake_Coarse.ts' geosurf = [[work_dir+'Till.ts',True,True], [work_dir+'XVK.ts',True,True], [work_dir+'PK1.ts',True,True], [work_dir+'PK2.ts',True,True], [work_dir+'PK3.ts',True,True], [work_dir+'HK1.ts',True,True], [work_dir+'VK.ts',True,True] ] # Background density bkgr = 1e-4 airc = 1e-8 # Units vals = np.asarray([1e-2,3e-2,5e-2,2e-2,2e-2,1e-3,5e-3]) #%% Script starts here # # Create a grid of observations and offset the z from topo model= np.ones(mesh.nC) * bkgr # Load GOCAD surf #[vrtx, trgl] = PF.BaseMag.read_GOCAD_ts(tsfile) # Find active cells from surface for ii in range(len(geosurf)): tin = tm.time() print "Computing indices with VTK: " + geosurf[ii][0] indx = gocad2simpegMeshIndex(geosurf[ii][0],mesh) print "VTK operation completed in " + str(tm.time() - tin) + " sec" model[indx] = vals[ii] indx = gocad2simpegMeshIndex(topsurf,mesh) actv = np.zeros(mesh.nC) actv[indx] = 1 model[actv==0] = airc Mesh.TensorMesh.writeModelUBC(mesh,'VTKout.dat',model)
def dynamicCells(self): if getattr(self, '_dynamicCells', None) is None: # Cells with value 1 in active model are dynamic dynamicCells = self.activeModel[self._activeCells] == 1 inds = np.asarray([inds for inds, elem in enumerate(dynamicCells, 1) if elem], dtype=int) - 1 self._dynamicCells = inds return self._dynamicCells
def activeCells(self): if getattr(self, '_activeCells', None) is None: if self.topofile == 'null': self._activeCells = np.arange(mesh.nC) else: topo = np.genfromtxt(self.basePath + self.topofile, skip_header=1) # Find the active cells active = Utils.surface2ind_topo(self.mesh,topo,'N') inds = np.asarray([inds for inds, elem in enumerate(active, 1) if elem], dtype = int) - 1 self._activeCells = inds return self._activeCells
def dynamicCells(self): if getattr(self, '_dynamicCells', None) is None: if getattr(self, '_staticInput', None) is None: # All cells are dynamic: 1's self._dynamicCells = np.arange(len(self.m0)) # Cells with specific value are static: 0's else: if isinstance(self._staticInput, float): dynamicCells = self.m0 != self._staticInput else: # Read from file active cells with 0:air, 1:dynamic, -1 static dynamicCells = Mesh.TensorMesh.readModelUBC(self.mesh, self.basePath + self._staticInput) dynamicCells = dynamicCells[self.activeCells] == 1 inds = np.asarray([inds for inds, elem in enumerate(dynamicCells, 1) if elem], dtype = int) - 1 self._dynamicCells = inds return self._dynamicCells
def r_unit(p1,p2): """ r_unit(x,y) : Function computes the unit vector between two points with coordinates p1(x1,y1) and p2(x2,y2) """ assert len(p1)==len(p2), 'locs must be the same shape.' dx = [] for ii in range(len(p1)): dx.append((p2[ii] - p1[ii])) # Compute length of vector r = np.linalg.norm(np.asarray(dx)) if r!=0: vec = dx/r else: vec = np.zeros(len(p1)) return vec, r
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True): """ DC Forward Simulation ===================== Forward model conductive spheres in a half-space and plot a pseudo-section Created by @fourndo on Mon Feb 01 19:28:06 2016 """ assert stype in ['pdp', 'dpdp'], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)" if loc is None: loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]] if sig is None: sig = np.r_[1e-2,1e-1,1e-3] if radi is None: radi = np.r_[25.,25.] if param is None: param = np.r_[30.,30.,5] # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx,15,-1.3), (dx, 75), (dx,15,1.3)] hyind = [(dx,15,-1.3), (dx, 10), (dx,15,1.3)] hzind = [(dx,15,-1.3),(dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:,0],radi[0],mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:,1],radi[1],mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy/2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 125 # Specify the survey type: "pdp" | "dpdp" # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh ends = [(-175,0),(175,0)] ends = np.c_[np.asarray(ends),np.ones(2).T*mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends ) 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 # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) # Define some global geometry dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) ) dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len dl_y = ( Tx[-1][1,1] - Tx[0][1,0] ) / dl_len azm = np.arctan(dl_y/dl_x) #Set boundary conditions mesh.setCellGradBC('neumann') # Define the differential operators needed for the DC problem Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1./(mesh.aveF2CC.T*(1./model))) A = Div*Msig*Grad # Change one corner to deal with nullspace A[0,0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1/dA,0,A.shape[0],A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations #print("Transmitter %i / %i\r" % (ii+1,len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii][:,0:3]) rxloc_N = np.asarray(Rx[ii][:,3:]) # For usual cases "dpdp" or "gradient" if stype == 'pdp': # Create an "inifinity" pole tx = np.squeeze(Tx[ii][:,0:1]) tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2 inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1] / mesh.vol[inds] ) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T ) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1,1] / mesh.vol[inds] ) # Iterative Solve Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1*phi - P2*phi)*np.pi data.append( dtemp ) print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time), print 'Transmitter {0} of {1}'.format(ii,len(Tx)) print 'Forward completed' # Let's just convert the 3D format into 2D (distance along line) and plot # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D.dobs =np.hstack(data) # Here is an example for the first tx-rx array if plotIt: import matplotlib.pyplot as plt fig = plt.figure() ax = plt.subplot(2,1,1, aspect='equal') mesh.plotSlice(np.log10(model), ax =ax, normal = 'Y', ind = indy,grid=True) ax.set_title('E-W section at '+str(mesh.vectorCCy[indy])+' m') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0][0,:],Tx[0][2,:],s=40,c='g', marker='v') plt.scatter(Rx[0][:,0::3],Rx[0][:,2::3],s=40,c='y') plt.xlim([-xlim,xlim]) plt.ylim([-zlim,mesh.vectorNz[-1]+dx]) ax = plt.subplot(2,1,2, aspect='equal') # Plot the location of the spheres for reference circle1=plt.Circle((loc[0,0]-Tx[0][0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3) circle2=plt.Circle((loc[0,1]-Tx[0][0,0],loc[2,1]),radi[1],color='k',fill=False, lw=3) ax.add_artist(circle1) ax.add_artist(circle2) # Add the speudo section DC.plot_pseudoSection(survey2D,ax,stype) # 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.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k') plt.ylim([-zlim,mesh.vectorNz[-1]+dx]) plt.show() return fig, ax
def convertObs_DC3D_to_2D(DCsurvey,lineID, flag = 'local'): """ Read DC survey and projects the coordinate system according to the flag = 'Xloc' | 'Yloc' | 'local' (default) In the 'local' system, station coordinates are referenced to distance from the first srcLoc[0].loc[0] The Z value is preserved, but Y coordinates zeroed. Input: :param survey3D Output: :figure survey2D Edited April 6th, 2016 @author: dominiquef """ from SimPEG import np def stn_id(v0,v1,r): """ Compute station ID along line """ dl = int(v0.dot(v1)) * r return dl srcLists = [] srcMat = getSrc_locs(DCsurvey) # Find all unique line id uniqueID = np.unique(lineID) for jj in range(len(uniqueID)): indx = np.where(lineID==uniqueID[jj])[0] # Find origin of survey r = 1e+8 # Initialize to some large number Tx = srcMat[indx] x0 = Tx[0][0,0:2] # Define station zero along line vecTx, r1 = r_unit(x0,Tx[-1][1,0:2]) for ii in range(len(indx)): # Get all receivers Rx = DCsurvey.srcList[indx[ii]].rxList[0].locs nrx = Rx[0].shape[0] if flag == 'local': # Find A electrode along line vec, r = r_unit(x0,Tx[ii][0,0:2]) A = stn_id(vecTx,vec,r) # Find B electrode along line vec, r = r_unit(x0,Tx[ii][1,0:2]) B = stn_id(vecTx,vec,r) M = np.zeros(nrx) N = np.zeros(nrx) for kk in range(nrx): # Find all M electrodes along line vec, r = r_unit(x0,Rx[0][kk,0:2]) M[kk] = stn_id(vecTx,vec,r) # Find all N electrodes along line vec, r = r_unit(x0,Rx[1][kk,0:2]) N[kk] = stn_id(vecTx,vec,r) elif flag == 'Yloc': """ Flip the XY axis locs""" A = Tx[ii][0,1] B = Tx[ii][1,1] M = Rx[0][:,1] N = Rx[1][:,1] elif flag == 'Xloc': """ Copy the rx-tx locs""" A = Tx[ii][0,0] B = Tx[ii][1,0] M = Rx[0][:,0] N = Rx[1][:,0] Rx = DC.RxDipole(np.c_[M,np.zeros(nrx),Rx[0][:,2]],np.c_[N,np.zeros(nrx),Rx[1][:,2]]) srcLists.append( DC.SrcDipole( [Rx], np.asarray([A,0,Tx[ii][0,2]]),np.asarray([B,0,Tx[ii][1,2]]) ) ) DCsurvey2D = DC.SurveyDC(srcLists) DCsurvey2D.dobs = np.asarray(DCsurvey.dobs) DCsurvey2D.std = np.asarray(DCsurvey.std) return DCsurvey2D
def readUBC_DC3Dobs(fileName, rtype = 'DC'): """ Read UBC GIF IP 3D observation file and generate survey :param string fileName:, path to the UBC GIF 3D obs file :rtype: Survey :return: DCIPsurvey """ zflag = True # Flag for z value provided # Load file if rtype == 'IP': obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='IPTYPE') elif rtype == 'DC': obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') else: print "rtype must be 'DC'(default) | 'IP'" # Pre-allocate srcLists = [] Rx = [] d = [] wd = [] # 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 or end of a transmitter block, read transmitter info if count==0: # 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[2:4],np.nan] zflag = False # Pass on the flag to the receiver loc else: tx = temp[:-1] rx = [] continue 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]) # Check if there is data with the location if len(temp)==8: d.append(temp[-2]) wd.append(temp[-1]) else: 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]) wd.append(temp[-1]) count = count -1 # 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:]) srcLists.append( DC.SrcDipole( [Rx], tx[:3],tx[3:]) ) # Create survey class survey = DC.SurveyDC(srcLists) survey.dobs = np.asarray(d) survey.std = np.asarray(wd) return {'DCsurvey':survey}
topsurf = work_dir+'CDED_Lake_Coarse.ts' geosurf = [[work_dir+'Till.ts',True,True], [work_dir+'XVK.ts',True,True], [work_dir+'PK1_extended.ts',True,True], [work_dir+'PK2.ts',True,True], [work_dir+'PK3.ts',True,True], [work_dir+'HK1.ts',True,True], [work_dir+'VK.ts',True,True] ] # Background density bkgr = 0 airc = 0 # Units vals = np.asarray([1,2,3,4,5,6,7]) #%% Script starts here # # Create a grid of observations and offset the z from topo model= np.ones(mesh.nC) * bkgr # Load GOCAD surf #[vrtx, trgl] = PF.BaseMag.read_GOCAD_ts(tsfile) # Find active cells from surface def read_GOCAD_ts(tsfile): """Read GOCAD triangulated surface (*.ts) file INPUT: tsfile: Triangulated surface OUTPUT:
def readUBC_DC3Dobs(fileName): from SimPEG import np """ Read UBC GIF DCIP 3D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 3D obs file Output: :param rx, tx, d, wd :return Created on Mon December 7th, 2015 @author: dominiquef """ # Load file obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') # Pre-allocate Tx = [] Rx = [] d = [] wd = [] # Countdown for number of obs/tx count = 0 for ii in range(obsfile.shape[0]): if not obsfile[ii]: continue # First line is transmitter with number of receivers if count==0: temp = (np.fromstring(obsfile[ii], dtype=float,sep=' ').T) count = int(temp[-1]) temp = np.reshape(temp[0:-1],[2,3]).T Tx.append(temp) rx = [] continue temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') rx.append(temp) count = count -1 # Reach the end of if count == 0: temp = np.asarray(rx) Rx.append(temp[:,0:6]) # Check for data + uncertainties if temp.shape[1]==8: d.append(temp[:,6]) wd.append(temp[:,7]) # Check for data only elif temp.shape[1]==7: d.append(temp[:,6]) return Tx, Rx, d, wd
def readUBC_DC2Dpre(fileName): """ Read UBC GIF DCIP 2D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 3D obs file Output: DCsurvey :return Created on Mon March 9th, 2016 << Doug's 70th Birthday !! >> @author: dominiquef """ # Load file obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') # Pre-allocate srcLists = [] Rx = [] d = [] zflag = True # Flag for z value provided for ii in range(obsfile.shape[0]): if not obsfile[ii]: continue # First line is transmitter with number of receivers temp = (np.fromstring(obsfile[ii], dtype=float,sep=' ').T) # Check if z value is provided, if False -> nan if len(temp)==5: tx = np.r_[temp[0],np.nan,np.nan,temp[1],np.nan,np.nan] zflag = False else: tx = np.r_[temp[0],np.nan,temp[1],temp[2],np.nan,temp[3]] if zflag: rx = np.c_[temp[4],np.nan,temp[5],temp[6],np.nan,temp[7]] else: rx = np.c_[temp[2],np.nan,np.nan,temp[3],np.nan,np.nan] # Check if there is data with the location d.append(temp[-1]) Rx = DC.RxDipole(rx[:,:3],rx[:,3:]) srcLists.append( DC.SrcDipole( [Rx], tx[:3],tx[3:]) ) # Create survey class survey = DC.SurveyDC(srcLists) survey.dobs = np.asarray(d) return {'DCsurvey':survey}
# Define a mesh cs = 0.5 hxind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)] hyind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)] hzind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC') # Get cells inside the sphere sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., rad) # Adjust susceptibility for volume difference Vratio = (4. / 3. * np.pi * rad**3.) / (np.sum(sph_ind) * cs**3.) model = np.ones(mesh.nC) * 1e-8 model[sph_ind] = 0.01 rxLoc = np.asarray([np.r_[0, 0, 4.]]) bzi = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'real') bzr = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'imag') freqs = [400] #np.logspace(2, 3, 5) srcLoc = np.r_[0, 0, 4.] srcList = [ FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z') for freq in freqs ] mapping = Maps.IdentityMap(mesh) surveyFD = FDEM.Survey(srcList) prbFD = FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=PardisoSolver)
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True): """ DC Forward Simulation ===================== Forward model conductive spheres in a half-space and plot a pseudo-section Created by @fourndo on Mon Feb 01 19:28:06 2016 """ assert stype in [ 'pdp', 'dpdp' ], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)" if loc is None: loc = np.c_[[-50., 0., -50.], [50., 0., -50.]] if sig is None: sig = np.r_[1e-2, 1e-1, 1e-3] if radi is None: radi = np.r_[25., 25.] if param is None: param = np.r_[30., 30., 5] # First we need to create a mesh and a model. # This is our mesh dx = 5. hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)] hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)] hzind = [(dx, 15, -1.3), (dx, 15)] mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN') # Set background conductivity model = np.ones(mesh.nC) * sig[0] # First anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC) model[ind] = sig[1] # Second anomaly ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC) model[ind] = sig[2] # Get index of the center indy = int(mesh.nCy / 2) # Plot the model for reference # Define core mesh extent xlim = 200 zlim = 125 # Specify the survey type: "pdp" | "dpdp" # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh ends = [(-175, 0), (175, 0)] ends = np.c_[np.asarray(ends), np.ones(2).T * mesh.vectorNz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, ends) 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 # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2]) # Define some global geometry dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2)) dl_x = (Tx[-1][0, 1] - Tx[0][0, 0]) / dl_len dl_y = (Tx[-1][1, 1] - Tx[0][1, 0]) / dl_len azm = np.arctan(dl_y / dl_x) #Set boundary conditions mesh.setCellGradBC('neumann') # Define the differential operators needed for the DC problem Div = mesh.faceDiv Grad = mesh.cellGrad Msig = Utils.sdiag(1. / (mesh.aveF2CC.T * (1. / model))) A = Div * Msig * Grad # Change one corner to deal with nullspace A[0, 0] = 1 A = sp.csc_matrix(A) # We will solve the system iteratively, so a pre-conditioner is helpful # This is simply a Jacobi preconditioner (inverse of the main diagonal) dA = A.diagonal() P = sp.spdiags(1 / dA, 0, A.shape[0], A.shape[0]) # Now we can solve the system for all the transmitters # We want to store the data data = [] # There is probably a more elegant way to do this, but we can just for-loop through the transmitters for ii in range(len(Tx)): start_time = time.time() # Let's time the calculations #print("Transmitter %i / %i\r" % (ii+1,len(Tx))) # Select dipole locations for receiver rxloc_M = np.asarray(Rx[ii][:, 0:3]) rxloc_N = np.asarray(Rx[ii][:, 3:]) # For usual cases "dpdp" or "gradient" if stype == 'pdp': # Create an "inifinity" pole tx = np.squeeze(Tx[ii][:, 0:1]) tinf = tx + np.array([dl_x, dl_y, 0]) * dl_len * 2 inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1] / mesh.vol[inds]) else: inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T) RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T * ([-1, 1] / mesh.vol[inds]) # Iterative Solve Ainvb = sp.linalg.bicgstab(P * A, P * RHS, tol=1e-5) # We now have the potential everywhere phi = Utils.mkvc(Ainvb[0]) # Solve for phi on pole locations P1 = mesh.getInterpolationMat(rxloc_M, 'CC') P2 = mesh.getInterpolationMat(rxloc_N, 'CC') # Compute the potential difference dtemp = (P1 * phi - P2 * phi) * np.pi data.append(dtemp) print '\rTransmitter {0} of {1} -> Time:{2} sec'.format( ii, len(Tx), time.time() - start_time), print 'Transmitter {0} of {1}'.format(ii, len(Tx)) print 'Forward completed' # Let's just convert the 3D format into 2D (distance along line) and plot # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc)) survey2D.dobs = np.hstack(data) # Here is an example for the first tx-rx array if plotIt: import matplotlib.pyplot as plt fig = plt.figure() ax = plt.subplot(2, 1, 1, aspect='equal') mesh.plotSlice(np.log10(model), ax=ax, normal='Y', ind=indy, grid=True) ax.set_title('E-W section at ' + str(mesh.vectorCCy[indy]) + ' m') plt.gca().set_aspect('equal', adjustable='box') plt.scatter(Tx[0][0, :], Tx[0][2, :], s=40, c='g', marker='v') plt.scatter(Rx[0][:, 0::3], Rx[0][:, 2::3], s=40, c='y') plt.xlim([-xlim, xlim]) plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) ax = plt.subplot(2, 1, 2, aspect='equal') # Plot the location of the spheres for reference circle1 = plt.Circle((loc[0, 0] - Tx[0][0, 0], loc[2, 0]), radi[0], color='w', fill=False, lw=3) circle2 = plt.Circle((loc[0, 1] - Tx[0][0, 0], loc[2, 1]), radi[1], color='k', fill=False, lw=3) ax.add_artist(circle1) ax.add_artist(circle2) # Add the speudo section DC.plot_pseudoSection(survey2D, ax, stype) # 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.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k') plt.ylim([-zlim, mesh.vectorNz[-1] + dx]) plt.show() return fig, ax
# Read in topo surface topsurf = "Topography_Local.ts" geosurf = [ ['_Top_Bollock_Rhyodacite_SUB.ts', False, True], ['_Top_Bollock_Rhyodacite_SUB_B.ts', False, True], ['_Top_Mafic_Intrusion.ts', True, True], ['_Top_Mafic_Volcaniclastic.ts', False, True], ['UnitA.ts', True, True], ['UnitB.ts', True, True], ['UnitC.ts', True, True], ['UnitD.ts', True, True], ['UnitE.ts', True, True], ['UnitF.ts', True, True], ] vals = np.asarray([0.005, 0.005, 0.01, 0.0025]) # Background density bkgr = 0.0001 # Offset data above topo zoffset = 2 #%% Script starts here # # Create a grid of observations and offset the z from topo #xr = np.linspace(mesh.vectorCCx[0], mesh.vectorCCx[-1], 99) #yr = np.linspace(mesh.vectorCCy[0], mesh.vectorCCy[-1], 74) xr = mesh.vectorCCx[::3] yr = mesh.vectorCCy[::3] X, Y = np.meshgrid(xr, yr)
def animate(ii): #for ii in range(1): removeFrame() # Grab current line and indx = np.where(lineID == ii)[0] srcLeft = [] obs_l = [] obs = [] srcRight = [] obs_r = [] srcList = [] # Split the obs file into left and right # Split the obs file into left and right for jj in range(len(indx)): # Grab corresponding data obs = np.hstack([obs, DCdobs2D.dobs[dataID == indx[jj]]]) #std = dobs2D.std[dataID==indx[jj]] srcList.append(DCdobs2D.srcList[indx[jj]]) Tx = DCdobs2D.srcList[indx[jj]].loc Rx = DCdobs2D.srcList[indx[jj]].rxList[0].locs # Create mid-point location Cmid = (Tx[0][0] + Tx[1][0]) / 2 Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2 ileft = Pmid < Cmid iright = Pmid >= Cmid temp = np.zeros(len(ileft)) temp[ileft] = 1 obs_l = np.hstack([obs_l, temp]) temp = np.zeros(len(iright)) temp[iright] = 1 obs_r = np.hstack([obs_r, temp]) if np.any(ileft): rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :]) srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1])) #std_l = np.hstack([std_l,std[ileft]]) if np.any(iright): rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :]) srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1])) #obs_r = np.hstack([obs_r,iright]) #std_r = np.hstack([std_r,std[iright]]) DC2D_full = DC.SurveyDC(srcList) DC2D_full.dobs = np.asarray(obs) DC2D_full.std = DC2D_full.dobs * 0. DC2D_full.std[obs_l == 1] = np.abs(DC2D_full.dobs[obs_l == 1]) * 0.02 + 2e-5 DC2D_full.std[obs_r == 1] = np.abs(DC2D_full.dobs[obs_r == 1]) * 0.06 + 4e-5 # DC2D_l = DC.SurveyDC(srcLeft) # DC2D_l.dobs = np.asarray(obs[obs_l==1]) # DC2D_l.std = np.abs(np.asarray(DC2D_l.dobs))*0.05 + 2e-5 # # DC2D_r = DC.SurveyDC(srcRight) # DC2D_r.dobs = np.asarray(obs[obs_r==1]) # DC2D_r.std = np.abs(np.asarray(DC2D_r.dobs))*0.05 + 2e-5 survey = DC2D_full # Export data file DC.writeUBC_DCobs(inv_dir + dsep + obsfile2d, survey, '2D', 'SIMPLE') # Write input file fid = open(inv_dir + dsep + inp_file, 'w') fid.write('OBS LOC_X %s \n' % obsfile2d) fid.write('MESH FILE %s \n' % mshfile2d) fid.write('CHIFACT 1 \n') fid.write('TOPO DEFAULT \n') fid.write('INIT_MOD VALUE %e\n' % ini_mod) fid.write('REF_MOD VALUE %e\n' % ref_mod) fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1)) fid.write('WEIGHT DEFAULT\n') fid.write('STORE_ALL_MODELS FALSE\n') fid.write('INVMODE CG\n') #fid.write('CG_PARAM 200 1e-4\n') fid.write('USE_MREF FALSE\n') #fid.write('BOUNDS VALUE 1e-4 1e+2\n') fid.close() os.chdir(inv_dir) os.system('dcinv2d ' + inp_file) #%% Load DC model and predicted data minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'dcinv2d.con') minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx)) #%% Repeat for IP data indx = np.where(IPlineID == ii)[0] srcLeft = [] obs_l = [] std_l = [] srcRight = [] obs_r = [] std_r = [] obs_full = [] std_full = [] srcList = [] # Split the obs file into left and right for jj in range(len(indx)): srcList.append(IPdobs2D.srcList[indx[jj]]) # Grab corresponding data obs = IPdobs2D.dobs[IPdataID == indx[jj]] std = IPdobs2D.std[IPdataID == indx[jj]] obs_full = np.hstack([obs_full, obs]) std_full = np.hstack([std_full, std]) Tx = IPdobs2D.srcList[indx[jj]].loc Rx = IPdobs2D.srcList[indx[jj]].rxList[0].locs # Create mid-point location Cmid = (Tx[0][0] + Tx[1][0]) / 2 Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2 ileft = Pmid < Cmid iright = Pmid >= Cmid temp = np.zeros(len(ileft)) temp[ileft] = 1 obs_l = np.hstack([obs_l, temp]) temp = np.zeros(len(iright)) temp[iright] = 1 obs_r = np.hstack([obs_r, temp]) if np.any(ileft): rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :]) srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1])) #std_l = np.hstack([std_l,std[ileft]]) if np.any(iright): rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :]) srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1])) IP2D_full = DC.SurveyDC(srcList) IP2D_full.dobs = np.asarray(obs_full) IP2D_full.std = np.asarray(std_full) IP2D_l = DC.SurveyDC(srcLeft) IP2D_l.dobs = np.asarray(obs_full[obs_l == 1]) #IP2D_l.std = np.abs(np.asarray(obs_l))*0.03 + 2e-2 IP2D_r = DC.SurveyDC(srcRight) IP2D_r.dobs = np.asarray(obs_full[obs_r == 1]) #IP2D_r.std = np.abs(np.asarray(obs_r))*0.03 + 1e-2 id_lbe = int(IPsurvey.srcList[indx[jj]].loc[0][1]) mesh3d = Mesh.TensorMesh([hx, np.ones(1) * 100., hz], x0=(-np.sum(padx) + np.min(srcMat[0][:, 0]), id_lbe - 50, np.max(srcMat[0][0, 2]) - np.sum(hz))) Mesh.TensorMesh.writeUBC(mesh3d, home_dir + dsep + 'Mesh' + str(id_lbe) + '.msh') global ax1, ax2, ax3, ax5, ax6, fig ax2 = plt.subplot(3, 2, 2) ph = DC.plot_pseudoSection(IP2D_r, ax2, stype='pdp', dtype='volt', colorbar=False) ax2.set_title('Observed P-DP', fontsize=10) plt.xlim([xmin, xmax]) plt.ylim([zmin, zmax]) plt.gca().set_aspect('equal', adjustable='box') ax2.set_xticklabels([]) ax2.set_yticklabels([]) ax1 = plt.subplot(3, 2, 1) DC.plot_pseudoSection(IP2D_l, ax1, stype='pdp', dtype='volt', clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]), colorbar=False) ax1.set_title('Observed DP-P', fontsize=10) plt.xlim([xmin, xmax]) plt.ylim([zmin, zmax]) plt.gca().set_aspect('equal', adjustable='box') ax1.set_xticklabels([]) z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5) z_label = np.linspace(20, 1, 5) ax1.set_yticks(map(int, z)) ax1.set_yticklabels(map(str, map(int, z_label)), size=8) ax1.set_ylabel('n-spacing', fontsize=8) #%% Add labels bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1) ax2.text(0.00, 1, 'A', transform=ax2.transAxes, ha="left", va="center", size=6, bbox=bbox_props) bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1) ax2.text(0.1, 1, 'M', transform=ax2.transAxes, ha="left", va="center", size=6, bbox=bbox_props) bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1) ax2.text(0.2, 1, 'N', transform=ax2.transAxes, ha="left", va="center", size=6, bbox=bbox_props) bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1) ax1.text(0.00, 1, 'N', transform=ax1.transAxes, ha="left", va="center", size=6, bbox=bbox_props) bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1) ax1.text(0.1, 1, 'M', transform=ax1.transAxes, ha="left", va="center", size=6, bbox=bbox_props) bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1) ax1.text(0.2, 1, 'A', transform=ax1.transAxes, ha="left", va="center", size=6, bbox=bbox_props) survey = IP2D_full # Export data file DC.writeUBC_DCobs(inv_dir + dsep + ipfile2d, survey, '2D', 'SIMPLE', iptype=1) fid = open(inv_dir + dsep + inp_file, 'w') fid.write('OBS LOC_X %s \n' % ipfile2d) fid.write('MESH FILE %s \n' % mshfile2d) fid.write('CHIFACT 4 \n') fid.write('COND FILE dcinv2d.con\n') fid.write('TOPO DEFAULT \n') fid.write('INIT_MOD VALUE %e\n' % ini_mod) fid.write('REF_MOD VALUE 0.0\n') fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1)) fid.write('WEIGHT DEFAULT\n') fid.write('STORE_ALL_MODELS FALSE\n') fid.write('INVMODE CG\n') #fid.write('CG_PARAM 200 1e-4\n') fid.write('USE_MREF FALSE\n') #fid.write('BOUNDS VALUE 1e-4 1e+2\n') fid.close() os.chdir(inv_dir) os.system('ipinv2d ' + inp_file) #%% Load model and predicted data minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'ipinv2d.chg') minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx)) Mesh.TensorMesh.writeModelUBC( mesh3d, home_dir + dsep + 'Model' + str(id_lbe) + '.chg', minv.T) dpre = DC.readUBC_DC2Dpre(inv_dir + dsep + 'ipinv2d.pre') DCpre = dpre['DCsurvey'] DCtemp = IP2D_l DCtemp.dobs = DCpre.dobs[obs_l == 1] ax5 = plt.subplot(3, 2, 3) DC.plot_pseudoSection(DCtemp, ax5, stype='pdp', dtype='volt', clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]), colorbar=False) ax5.set_title('Predicted', fontsize=10) plt.xlim([xmin, xmax]) plt.ylim([zmin, zmax]) plt.gca().set_aspect('equal', adjustable='box') ax5.set_xticklabels([]) z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5) z_label = np.linspace(20, 1, 5) ax5.set_yticks(map(int, z)) ax5.set_yticklabels(map(str, map(int, z_label)), size=8) ax5.set_ylabel('n-spacing', fontsize=8) DCtemp = IP2D_r DCtemp.dobs = DCpre.dobs[obs_r == 1] ax6 = plt.subplot(3, 2, 4) DC.plot_pseudoSection(DCtemp, ax6, stype='pdp', dtype='volt', clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]), colorbar=False) ax6.set_title('Predicted', fontsize=10) plt.xlim([xmin, xmax]) plt.ylim([zmin, zmax]) plt.gca().set_aspect('equal', adjustable='box') ax6.set_xticklabels([]) ax6.set_yticklabels([]) pos = ax6.get_position() cbarax = fig.add_axes([ pos.x0 + 0.325, pos.y0 + 0.2, pos.width * 0.1, pos.height * 0.5 ]) ## the parameters are the specified position you set cb = fig.colorbar(ph[0], cax=cbarax, orientation="vertical", ax=ax6, ticks=np.linspace(ph[0].get_clim()[0], ph[0].get_clim()[1], 4), format="$10^{%.1f}$") cb.set_label("App. Charg.", size=8) ax3 = plt.subplot(3, 1, 3) ax3.set_title('2-D Model (S/m)', fontsize=10) ax3.set_xticks(map(int, x)) ax3.set_xticklabels(map(str, map(int, x))) ax3.set_xlabel('Easting (m)', fontsize=8) ax3.set_yticks(map(int, z)) ax3.set_yticklabels(map(str, map(int, z)), rotation='vertical') ax3.set_ylabel('Depth (m)', fontsize=8) plt.xlim([xmin, xmax]) plt.ylim([zmin / 2, zmax]) plt.gca().set_aspect('equal', adjustable='box') ph2 = plt.pcolormesh(mesh2d.vectorNx, mesh2d.vectorNy, (minv), vmin=vmin, vmax=vmax) plt.gca().tick_params(axis='both', which='major', labelsize=8) plt.draw() for ss in range(survey.nSrc): Tx = survey.srcList[ss].loc[0] plt.scatter(Tx[0], mesh2d.vectorNy[-1] + 10, s=10) pos = ax3.get_position() ax3.set_position([pos.x0 + 0.025, pos.y0, pos.width, pos.height]) pos = ax3.get_position() cbarax = fig.add_axes([ pos.x0 + 0.65, pos.y0 + 0.01, pos.width * 0.05, pos.height * 0.75 ]) ## the parameters are the specified position you set cb = fig.colorbar(ph2, cax=cbarax, orientation="vertical", ax=ax3, ticks=np.linspace(vmin, vmax, 4), format="%4.1f") cb.set_label("Chargeability", size=8) pos = ax1.get_position() ax1.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height]) pos = ax5.get_position() ax5.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height]) pos = ax2.get_position() ax2.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height]) pos = ax6.get_position() ax6.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height]) #%% Add the extra bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="w", ec="k", lw=2) ax2.text(0.01, (float(ii) + 1.) / (len(uniqueID) + 2), 'N: ' + str(id_lbe), transform=fig.transFigure, ha="left", va="center", size=8, bbox=bbox_props) mrk_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=2) ax2.text(0.01, 0.9, 'Line ID#', transform=fig.transFigure, ha="left", va="center", size=8, bbox=mrk_props) mrk_props = dict(boxstyle="square,pad=0.3", fc="b", ec="k", lw=2) for jj in range(len(uniqueID)): ax2.text(0.1, (float(jj) + 1.) / (len(uniqueID) + 2), ".", transform=fig.transFigure, ha="right", va="center", size=8, bbox=mrk_props) mrk_props = dict(boxstyle="square,pad=0.3", fc="r", ec="k", lw=2) ax2.text(0.1, (float(ii) + 1.) / (len(uniqueID) + 2), ".", transform=fig.transFigure, ha="right", va="center", size=8, bbox=mrk_props)
topo = np.genfromtxt(home_dir + dsep + topo_file, skip_header=1) Ftopo = NearestNDInterpolator(topo[:, :2], topo[:, 2]) # Forward solver # Number of padding cells to remove from plotting padc = 15 # Plotting parameters xmin, xmax = 10500, 13000 zmin, zmax = -600, 600 vmin, vmax = 0, 75 z = np.linspace(zmin, zmax, 4) x = np.asarray([11000, 11750, 12500]) #%% load obs file 3D dobs = DC.readUBC_DC3Dobs(home_dir + dsep + DCobs_file) DCsurvey = dobs['DCsurvey'] dobs = DC.readUBC_DC3Dobs(home_dir + dsep + IPobs_file, rtype='IP') IPsurvey = dobs['DCsurvey'] # Assign Z-value from topo for ii in range(IPsurvey.nSrc): IPsurvey.srcList[ii].loc[0][2] = Ftopo(IPsurvey.srcList[ii].loc[0][0:2]) IPsurvey.srcList[ii].loc[1][2] = Ftopo(IPsurvey.srcList[ii].loc[1][0:2]) rx_x = IPsurvey.srcList[ii].rxList[0].locs[0][:, 0] rx_y = IPsurvey.srcList[ii].rxList[0].locs[0][:, 1] IPsurvey.srcList[ii].rxList[0].locs[0][:, 2] = Ftopo(rx_x, rx_y)
#if re.match(stype,'gradient'): gin = [(400.,12200.), (1800.,12200.)] #else: #gin = plt.ginput(2, timeout = 0) #============================================================================== # if not gin: # print 'SimPED - Simulation has ended with return' # break #============================================================================== # Add z coordinate to all survey... assume flat nz = mesh.vectorNz var = np.c_[np.asarray(gin),np.ones(2).T*nz[-1]] # Snap the endpoints to the grid. Easier to create 2D section. indx = Utils.closestPoints(mesh, var ) endl = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*nz[-1]] [Tx, Rx] = DC.gen_DCIPsurvey(endl, mesh, stype, a, b, n) dl_len = np.sqrt( np.sum((endl[0,:] - endl[1,:])**2) ) dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len dl_y = ( Tx[-1][1,1] - Tx[0][1,0] ) / dl_len azm = np.arctan(dl_y/dl_x) # Plot stations along line plt.scatter(Tx[0][0,:],Tx[0][1,:],s=20,c='g') plt.scatter(Rx[0][:,0::3],Rx[0][:,1::3],s=20,c='y')
def readUBC_DC3Dobstopo(filename,mesh,topo,probType="CC"): """ Seogi's personal readObs function. """ text_file = open(filename, "r") lines = text_file.readlines() text_file.close() SRC = [] DATA = [] srcLists = [] isrc = 0 # airind = getActiveindfromTopo(mesh, topo) # mesh2D, topoCC = gettopoCC(mesh, airind) for line in lines: if "!" in line.split(): continue elif line == '\n': continue elif line == ' \n': continue temp = map(float, line.split()) # Read a line for the current electrode if len(temp) == 5: # SRC: Only X and Y are provided (assume no topography) #TODO consider topography and assign the closest cell center in the earth if isrc == 0: DATA_temp = [] else: DATA.append(np.asarray(DATA_temp)) DATA_temp = [] indM = Utils.closestPoints(mesh2D, DATA[isrc-1][:,1:3]) indN = Utils.closestPoints(mesh2D, DATA[isrc-1][:,3:5]) rx = DCIP.RxDipole(np.c_[DATA[isrc-1][:,1:3], topoCC[indM]], np.c_[DATA[isrc-1][:,3:5], topoCC[indN]]) temp = np.asarray(temp) if [SRC[isrc-1][0], SRC[isrc-1][1]] == [SRC[isrc-1][2], SRC[isrc-1][3]]: indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]]) tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[mesh.vectorCCx.max(), mesh.vectorCCy.max(), topoCC[-1]]) else: indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]]) indB = Utils.closestPoints(mesh2D, [SRC[isrc-1][2], SRC[isrc-1][3]]) tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[SRC[isrc-1][2], SRC[isrc-1][3], topoCC[indB]]) srcLists.append(tx) SRC.append(temp) isrc += 1 elif len(temp) == 7: # SRC: X, Y and Z are provided SRC.append(temp) isrc += 1 elif len(temp) == 6: # DATA_temp.append(np.r_[isrc, np.asarray(temp)]) elif len(temp) > 7: DATA_temp.append(np.r_[isrc, np.asarray(temp)]) DATA.append(np.asarray(DATA_temp)) DATA_temp = [] indM = Utils.closestPoints(mesh2D, DATA[isrc-1][:,1:3]) indN = Utils.closestPoints(mesh2D, DATA[isrc-1][:,3:5]) rx = DCIP.RxDipole(np.c_[DATA[isrc-1][:,1:3], topoCC[indM]], np.c_[DATA[isrc-1][:,3:5], topoCC[indN]]) temp = np.asarray(temp) if [SRC[isrc-1][0], SRC[isrc-1][1]] == [SRC[isrc-1][2], SRC[isrc-1][3]]: indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]]) tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[mesh.vectorCCx.max(), mesh.vectorCCy.max(), topoCC[-1]]) else: indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]]) indB = Utils.closestPoints(mesh2D, [SRC[isrc-1][2], SRC[isrc-1][3]]) tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[SRC[isrc-1][2], SRC[isrc-1][3], topoCC[indB]]) srcLists.append(tx) text_file.close() survey = DCIP.SurveyDC(srcLists) # Do we need this? SRC = np.asarray(SRC) DATA = np.vstack(DATA) survey.dobs = np.vstack(DATA)[:,-2] return {'DCsurvey':survey, 'airind':airind, 'topoCC':topoCC, 'SRC':SRC}
def convertObs_DC3D_to_2D(DCsurvey,lineID): """ Read DC survey and data and change coordinate system to distance along line assuming all data is acquired along line. First transmitter pole is assumed to be at the origin Assumes flat topo for now... Input: :param Tx, Rx Output: :figure Tx2d, Rx2d Edited Feb 17th, 2016 @author: dominiquef """ from SimPEG import np def stn_id(v0,v1,r): """ Compute station ID along line """ dl = int(v0.dot(v1)) * r return dl srcLists = [] srcMat = getSrc_locs(DCsurvey) # Find all unique line id uniqueID = np.unique(lineID) for jj in range(len(uniqueID)): indx = np.where(lineID==uniqueID[jj])[0] # Find origin of survey r = 1e+8 # Initialize to some large number Tx = srcMat[indx] x0 = Tx[0][0,0:2] # Define station zero along line vecTx, r1 = r_unit(x0,Tx[-1][1,0:2]) for ii in range(len(indx)): # Get all receivers Rx = DCsurvey.srcList[indx[ii]].rxList[0].locs nrx = Rx[0].shape[0] # Find A electrode along line vec, r = r_unit(x0,Tx[ii][0,0:2]) A = stn_id(vecTx,vec,r) # Find B electrode along line vec, r = r_unit(x0,Tx[ii][1,0:2]) B = stn_id(vecTx,vec,r) M = np.zeros(nrx) N = np.zeros(nrx) for kk in range(nrx): # Find all M electrodes along line vec, r = r_unit(x0,Rx[0][kk,0:2]) M[kk] = stn_id(vecTx,vec,r) # Find all N electrodes along line vec, r = r_unit(x0,Rx[1][kk,0:2]) N[kk] = stn_id(vecTx,vec,r) Rx = DC.RxDipole(np.c_[M,np.zeros(nrx),Rx[0][:,2]],np.c_[N,np.zeros(nrx),Rx[1][:,2]]) srcLists.append( DC.SrcDipole( [Rx], np.asarray([A,0,Tx[ii][0,2]]),np.asarray([B,0,Tx[ii][1,2]]) ) ) DCsurvey2D = DC.SurveyDC(srcLists) DCsurvey2D.dobs = np.asarray(DCsurvey.dobs) DCsurvey2D.std = np.asarray(DCsurvey.std) return DCsurvey2D
def readUBC_DC3Dobs(fileName): """ Read UBC GIF DCIP 3D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 3D obs file Output: :param rx, tx, d, wd :return Created on Mon December 7th, 2015 @author: dominiquef """ # Load file obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') # 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]): if not obsfile[ii]: continue # First line is transmitter with number of receivers if count==0: 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 else: tx = temp[:-1] rx = [] continue temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') if zflag: rx.append(temp[:-2]) # Check if there is data with the location if len(temp)==8: d.append(temp[-2]) wd.append(temp[-1]) else: rx.append(np.r_[temp[0:2],np.nan,temp[0:2],np.nan] ) # Check if there is data with the location if len(temp)==6: d.append(temp[-2]) wd.append(temp[-1]) count = count -1 # Reach the end of transmitter block if count == 0: rx = np.asarray(rx) Rx = DC.RxDipole(rx[:,:3],rx[:,3:]) srcLists.append( DC.SrcDipole( [Rx], tx[:3],tx[3:]) ) # Create survey class survey = DC.SurveyDC(srcLists) survey.dobs = np.asarray(d) survey.std = np.asarray(wd) return {'DCsurvey':survey}
#%% # Display top section top = int(mesh.nCz) - 1 mesh.plotSlice(model, ind=top, normal='Z', grid=True, pcolorOpts={'alpha': 0.8}) ylim = (546000, 546750) xlim = (422900, 423675) # Takes two points from ginput and create survey temp = plt.ginput(2) # Add z coordinate nz = mesh.vectorNz endp = np.c_[np.asarray(temp), np.ones(2).T * nz[-1]] # Create dipole survey receivers and plot nrx = 10 ab = 40 a = 20 # Evenly distribute transmitters for now and put on surface dplen = np.sqrt(np.sum((endp[1, :] - endp[0, :])**2)) dp_x = (endp[1, 0] - endp[0, 0]) / dplen dp_y = (endp[1, 1] - endp[0, 1]) / dplen nstn = np.floor(dplen / ab) stn_x = endp[0, 0] + np.cumsum(np.ones(nstn) * dp_x * ab) stn_y = endp[0, 1] + np.cumsum(np.ones(nstn) * dp_y * ab)
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