def setUp(self): cs = 12.5 hx = [(cs,7, -1.3),(cs,61),(cs,7, 1.3)] hy = [(cs,7, -1.3),(cs,20)] mesh = Mesh.TensorMesh([hx, hy],x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC)*sighalf x = np.linspace(-135, 250., 20) M = Utils.ndgrid(x-12.5, np.r_[0.]) N = Utils.ndgrid(x+12.5, np.r_[0.]) 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, earth_type="halfspace") rx = DC.Rx.Dipole_ky(M, N) src0 = DC.Src.Pole([rx], A0loc) survey = DC.Survey_ky([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_anal = data_anal try: from pymatsolver import MumpsSolver self.Solver = MumpsSolver except ImportError, e: self.Solver = SolverLU
def setUp(self): cs = 12.5 hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)] hy = [(cs, 7, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy], x0="CN") sighalf = 1e-2 sigma = np.ones(mesh.nC) * sighalf x = np.linspace(-135, 250., 20) M = Utils.ndgrid(x - 12.5, np.r_[0.]) N = Utils.ndgrid(x + 12.5, np.r_[0.]) 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.DCAnalytic_Pole_Dipole(np.r_[A0loc, 0.], rxloc, sighalf, earth_type="halfspace") rx = DC.Rx.Dipole_ky(M, N) src0 = DC.Src.Pole([rx], A0loc) survey = DC.Survey_ky([src0]) self.survey = survey self.mesh = mesh self.sigma = sigma self.data_anal = data_anal try: from pymatsolver import PardisoSolver self.Solver = PardisoSolver except ImportError: self.Solver = SolverLU
def run(plotIt=True, nFreq=1): """ MT: 3D: Forward =============== Forward model 3D MT data. """ # Make a mesh M = simpeg.Mesh.TensorMesh([[(100,5,-1.5),(100.,10),(100,5,1.5)],[(100,5,-1.5),(100.,10),(100,5,1.5)],[(100,5,1.6),(100.,10),(100,3,2)]], x0=['C','C',-3529.5360]) # Setup the model conds = [1e-2,1] sig = simpeg.Utils.ModelBuilder.defineBlock(M.gridCC,[-1000,-1000,-400],[1000,1000,-200],conds) sig[M.gridCC[:,2]>0] = 1e-8 sig[M.gridCC[:,2]<-600] = 1e-1 sigBG = np.zeros(M.nC) + conds[0] sigBG[M.gridCC[:,2]>0] = 1e-8 ## Setup the the survey object # Receiver locations rx_x, rx_y = np.meshgrid(np.arange(-500,501,50),np.arange(-500,501,50)) rx_loc = np.hstack((simpeg.Utils.mkvc(rx_x,2),simpeg.Utils.mkvc(rx_y,2),np.zeros((np.prod(rx_x.shape),1)))) # Make a receiver list rxList = [] for loc in rx_loc: # NOTE: loc has to be a (1,3) np.ndarray otherwise errors accure for rx_orientation in ['xx','xy','yx','yy']: rxList.append(NSEM.Rx.Point_impedance3D(simpeg.mkvc(loc,2).T,rx_orientation, 'real')) rxList.append(NSEM.Rx.Point_impedance3D(simpeg.mkvc(loc,2).T,rx_orientation, 'imag')) for rx_orientation in ['zx','zy']: rxList.append(NSEM.Rx.Point_tipper3D(simpeg.mkvc(loc,2).T,rx_orientation, 'real')) rxList.append(NSEM.Rx.Point_tipper3D(simpeg.mkvc(loc,2).T,rx_orientation, 'imag')) # Source list srcList =[] for freq in np.logspace(3,-3,nFreq): srcList.append(NSEM.Src.Planewave_xy_1Dprimary(rxList,freq)) # Survey MT survey = NSEM.Survey(srcList) ## Setup the problem object problem = NSEM.Problem3D_ePrimSec(M, sigmaPrimary=sigBG) problem.pair(survey) problem.Solver = Solver # Calculate the data fields = problem.fields(sig) dataVec = survey.eval(fields) # Make the data mtData = NSEM.Data(survey,dataVec) # Add plots if plotIt: pass
def readMagneticsObservations(self, obs_file): """ Read and write UBC mag file format INPUT: :param fileName, path to the UBC obs mag file OUTPUT: :param survey :param M, magnetization orentiaton (MI, MD) """ fid = open(self.basePath + obs_file, 'r') # First line has the inclination,declination and amplitude of B0 line = fid.readline() B = np.array(line.split(), dtype=float) # Second line has the magnetization orientation and a flag line = fid.readline() M = np.array(line.split(), dtype=float) # Third line has the number of rows line = fid.readline() ndat = np.array(line.split(), dtype=int) # Pre-allocate space for obsx, obsy, obsz, data, uncert line = fid.readline() temp = np.array(line.split(), dtype=float) d = np.zeros(ndat, dtype=float) wd = np.zeros(ndat, dtype=float) locXYZ = np.zeros((ndat[0], 3), dtype=float) for ii in range(ndat): temp = np.array(line.split(), dtype=float) locXYZ[ii, :] = temp[:3] if len(temp) > 3: d[ii] = temp[3] if len(temp) == 5: wd[ii] = temp[4] line = fid.readline() rxLoc = BaseMag.RxObs(locXYZ) srcField = BaseMag.SrcField([rxLoc], param=(B[2], B[0], B[1])) survey = BaseMag.LinearSurvey(srcField) survey.dobs = d survey.std = wd return survey
def getInitialFields(self): Srcs = self.survey.srcList if self._fieldType is 'b' or self._fieldType is 'j': ifields = np.zeros((self.mesh.nF, len(Srcs))) elif self._fieldType is 'e' or self._fieldType is 'h': ifields = np.zeros((self.mesh.nE, len(Srcs))) for i, src in enumerate(Srcs): ifields[:, i] = (ifields[:, i] + getattr(src, '{}Initial'.format(self._fieldType), None)(self)) return ifields
def getInitialFields(self): Srcs = self.survey.srcList if self._fieldType is 'b' or self._fieldType is 'j': ifields = np.zeros((self.mesh.nF, len(Srcs))) elif self._fieldType is 'e' or self._fieldType is 'h': ifields = np.zeros((self.mesh.nE, len(Srcs))) for i, src in enumerate(Srcs): ifields[:, i] = ( ifields[:, i] + getattr(src, '{}Initial'.format(self._fieldType), None)(self)) return ifields
def __init__(self, h_in, x0_in=None): assert type(h_in) in [list, tuple], 'h_in must be a list' assert len(h_in) in [1,2,3], 'h_in must be of dimension 1, 2, or 3' h = range(len(h_in)) for i, h_i in enumerate(h_in): if Utils.isScalar(h_i) and type(h_i) is not np.ndarray: # This gives you something over the unit cube. h_i = self._unitDimensions[i] * np.ones(int(h_i))/int(h_i) elif type(h_i) is list: h_i = Utils.meshTensor(h_i) assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) h[i] = h_i[:] # make a copy. x0 = np.zeros(len(h)) if x0_in is not None: assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" for i in range(len(h)): x_i, h_i = x0_in[i], h[i] if Utils.isScalar(x_i): x0[i] = x_i elif x_i == '0': x0[i] = 0.0 elif x_i == 'C': x0[i] = -h_i.sum()*0.5 elif x_i == 'N': x0[i] = -h_i.sum() else: raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i) BaseRectangularMesh.__init__(self, np.array([x.size for x in h]), x0) # Ensure h contains 1D vectors self._h = [Utils.mkvc(x.astype(float)) for x in h]
def fget(self): if(self._vol is None): if self.dim == 2: A, B, C, D = Utils.indexCube('ABCD', self.vnC+1) normal, area = Utils.faceInfo(np.c_[self.gridN, np.zeros((self.nN, 1))], A, B, C, D) self._vol = area elif self.dim == 3: # Each polyhedron can be decomposed into 5 tetrahedrons # However, this presents a choice so we may as well divide in two ways and average. A, B, C, D, E, F, G, H = Utils.indexCube('ABCDEFGH', self.vnC+1) vol1 = (Utils.volTetra(self.gridN, A, B, D, E) + # cutted edge top Utils.volTetra(self.gridN, B, E, F, G) + # cutted edge top Utils.volTetra(self.gridN, B, D, E, G) + # middle Utils.volTetra(self.gridN, B, C, D, G) + # cutted edge bottom Utils.volTetra(self.gridN, D, E, G, H)) # cutted edge bottom vol2 = (Utils.volTetra(self.gridN, A, F, B, C) + # cutted edge top Utils.volTetra(self.gridN, A, E, F, H) + # cutted edge top Utils.volTetra(self.gridN, A, H, F, C) + # middle Utils.volTetra(self.gridN, C, H, D, A) + # cutted edge bottom Utils.volTetra(self.gridN, C, G, H, F)) # cutted edge bottom self._vol = (vol1 + vol2)/2 return self._vol
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 _bPrimary(self, eSolution, srcList): bPrimary = np.zeros([self.survey.mesh.nE, eSolution.shape[1]], dtype=complex) for i, src in enumerate(srcList): bp = src.bPrimary(self.survey.prob) if bp is not None: bPrimary[:, i] += bp[:, -1] return bPrimary
def setUp(self): cs = 12.5 npad = 2 hx = [(cs, npad, -1.3), (cs, 21), (cs, npad, 1.3)] hy = [(cs, npad, -1.3), (cs, 21), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN") x = mesh.vectorCCx[(mesh.vectorCCx > -80.) & (mesh.vectorCCx < 80.)] y = mesh.vectorCCx[(mesh.vectorCCy > -80.) & (mesh.vectorCCy < 80.)] Aloc = np.r_[-100., 0., 0.] Bloc = np.r_[100., 0., 0.] M = Utils.ndgrid(x - 12.5, y, np.r_[0.]) N = Utils.ndgrid(x + 12.5, y, np.r_[0.]) radius = 50. xc = np.r_[0., 0., -100] blkind = Utils.ModelBuilder.getIndicesSphere(xc, radius, mesh.gridCC) sigmaInf = np.ones(mesh.nC) * 1e-2 eta = np.zeros(mesh.nC) eta[blkind] = 0.1 sigma0 = sigmaInf * (1. - eta) rx = DC.Rx.Dipole(M, N) src = DC.Src.Dipole([rx], Aloc, Bloc) surveyDC = DC.Survey([src]) self.surveyDC = surveyDC self.mesh = mesh self.sigmaInf = sigmaInf self.sigma0 = sigma0 self.src = src self.eta = eta
def _bPrimary(self, eSolution, srcList): bPrimary = np.zeros([self.survey.mesh.nE,eSolution.shape[1]], dtype = complex) for i, src in enumerate(srcList): bp = src.bPrimary(self.survey.prob) if bp is not None: bPrimary[:,i] += bp[:,-1] return bPrimary
def setUp(self): cs = 25. hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)] hz = [(cs, 0, -1.3), (cs, 20)] mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN") blkind0 = Utils.ModelBuilder.getIndicesSphere( np.r_[-100., -100., -200.], 75., mesh.gridCC ) blkind1 = Utils.ModelBuilder.getIndicesSphere( np.r_[100., 100., -200.], 75., mesh.gridCC ) sigma = np.ones(mesh.nC)*1e-2 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma)*1. eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.01 x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)] y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x-25., y, np.r_[0.]) N = Utils.ndgrid(x+25., y, np.r_[0.]) times = np.arange(10)*1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC)) problem = SIP.Problem3D_N( mesh, sigma=sigma, etaMap=wires.eta, tauiMap=wires.taui ) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta, 1./tau] survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) reg = Regularization.Tikhonov(mesh) opt = Optimization.InexactGaussNewton( maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6 ) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
def _ePrimary(self, bSolution, srcList): ePrimary = np.zeros([self._edgeCurl.shape[1],bSolution.shape[1]],dtype = complex) for i,src in enumerate(srcList): ep = src.ePrimary(self.prob) if ep is not None: ePrimary[:,i] = ep return ePrimary
def _hPrimary(self, jSolution, srcList): hPrimary = np.zeros([self._edgeCurl.shape[1],jSolution.shape[1]],dtype = complex) for i, src in enumerate(srcList): hp = src.hPrimary(self.prob) if hp is not None: hPrimary[:,i] = hp return hPrimary
def _bPrimary(self, eSolution, srcList): bPrimary = np.zeros([self._edgeCurl.shape[0],eSolution.shape[1]],dtype = complex) for i, src in enumerate(srcList): bp = src.bPrimary(self.prob) if bp is not None: bPrimary[:,i] += bp return bPrimary
def _jPrimary(self, hSolution, srcList): jPrimary = np.zeros([self._edgeCurl.shape[0], hSolution.shape[1]], dtype = complex) for i, src in enumerate(srcList): jp = src.jPrimary(self.prob) if jp is not None: jPrimary[:,i] = jp return jPrimary
def vol(self): """ Construct cell volumes of the 3D model as 1d array """ if getattr(self, '_vol', None) is None: if self.dim == 2: A, B, C, D = Utils.indexCube('ABCD', self.vnC+1) normal, area = Utils.faceInfo(np.c_[self.gridN, np.zeros( (self.nN, 1))], A, B, C, D) self._vol = area elif self.dim == 3: # Each polyhedron can be decomposed into 5 tetrahedrons # However, this presents a choice so we may as well divide in # two ways and average. A, B, C, D, E, F, G, H = Utils.indexCube('ABCDEFGH', self.vnC + 1) vol1 = (Utils.volTetra(self.gridN, A, B, D, E) + # cutted edge top Utils.volTetra(self.gridN, B, E, F, G) + # cutted edge top Utils.volTetra(self.gridN, B, D, E, G) + # middle Utils.volTetra(self.gridN, B, C, D, G) + # cutted edge bottom Utils.volTetra(self.gridN, D, E, G, H)) # cutted edge bottom vol2 = (Utils.volTetra(self.gridN, A, F, B, C) + # cutted edge top Utils.volTetra(self.gridN, A, E, F, H) + # cutted edge top Utils.volTetra(self.gridN, A, H, F, C) + # middle Utils.volTetra(self.gridN, C, H, D, A) + # cutted edge bottom Utils.volTetra(self.gridN, C, G, H, F)) # cutted edge bottom self._vol = (vol1 + vol2)/2 return self._vol
def getInitialFieldsDeriv(self, src, v, adjoint=False): if adjoint is False: if self._fieldType is 'b' or self._fieldType is 'j': ifieldsDeriv = np.zeros(self.mesh.nF) elif self._fieldType is 'e' or self._fieldType is 'h': ifieldsDeriv = np.zeros(self.mesh.nE) elif adjoint is True: ifieldsDeriv = np.zeros(self.mapping.nP) ifieldsDeriv = (Utils.mkvc( getattr(src, '{}InitialDeriv'.format(self._fieldType), None)( self, v, adjoint)) + ifieldsDeriv) return ifieldsDeriv
def Jtvec(self, m, v, u=None): """ Sensitivity transpose times a vector :param numpy.array m: inversion model (nP,) :param numpy.array v: vector which we take adjoint product with (nP,) :param SimPEG.EM.FDEM.Fields u: fields object :rtype numpy.array: :return: Jv (ndata,) """ if u is None: u = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): ftype = self._fieldType + 'Solution' u_src = u[src, ftype] for rx in src.rxList: PTv = rx.projectFieldsDeriv(src, self.mesh, u, v[src, rx], adjoint=True) # wrt u, need possibility wrt m df_duTFun = getattr(u, '_%sDeriv_u'%rx.projField, None) df_duT = df_duTFun(src, PTv, adjoint=True) ATinvdf_duT = ATinv * df_duT dA_dmT = self.getADeriv_m(freq, u_src, ATinvdf_duT, adjoint=True) dRHS_dmT = self.getRHSDeriv_m(freq,src, ATinvdf_duT, adjoint=True) du_dmT = -dA_dmT + dRHS_dmT df_dmFun = getattr(u, '_%sDeriv_m'%rx.projField, None) dfT_dm = df_dmFun(src, PTv, adjoint=True) du_dmT += dfT_dm # TODO: this should be taken care of by the reciever real_or_imag = rx.projComp if real_or_imag is 'real': Jtv += np.array(du_dmT,dtype=complex).real elif real_or_imag is 'imag': Jtv += - np.array(du_dmT,dtype=complex).real else: raise Exception('Must be real or imag') ATinv.clean() return Utils.mkvc(Jtv)
def __init__(self, h_in, x0=None): assert type(h_in) is list, 'h_in must be a list' assert len(h_in) > 1, "len(h_in) must be greater than 1" h = range(len(h_in)) for i, h_i in enumerate(h_in): if type(h_i) in [int, long, float]: # This gives you something over the unit cube. h_i = np.ones(int(h_i))/int(h_i) assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i) assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i) h[i] = h_i[:] # make a copy. self.h = h if x0 is None: x0 = np.zeros(self.dim) else: assert type(x0) in [list, np.ndarray], 'x0 must be a numpy array or a list' x0 = np.array(x0, dtype=float) assert len(x0) == self.dim, 'x0 must have the same dimensions as the mesh' # TODO: this has a lot of stuff which doesn't work for this style of mesh... BaseMesh.__init__(self, np.array([x.size for x in h]), x0) # set the sets for holding the cells, nodes, faces, and edges self.cells = set() self.nodes = set() self.faces = set() self.facesX = set() self.facesY = set() if self.dim == 3: self.facesZ = set() self.edges = set() self.edgesX = set() self.edgesY = set() self.edgesZ = set() self.children = np.empty([hi.size for hi in h],dtype=TreeCell) if self.dim == 2: for i in range(h[0].size): for j in range(h[1].size): fXm = None if i is 0 else self.children[i-1][j].fXp fYm = None if j is 0 else self.children[i][j-1].fYp x0i = (np.r_[x0[0], h[0][:i]]).sum() x0j = (np.r_[x0[1], h[1][:j]]).sum() self.children[i][j] = TreeCell(self, x0=[x0i, x0j], depth=0, sz=[h[0][i], h[1][j]], fXm=fXm, fYm=fYm) elif self.dim == 3: for i in range(h[0].size): for j in range(h[1].size): for k in range(h[2].size): fXm = None if i is 0 else self.children[i-1][j][k].fXp fYm = None if j is 0 else self.children[i][j-1][k].fYp fZm = None if k is 0 else self.children[i][j][k-1].fZp x0i = (np.r_[x0[0], h[0][:i]]).sum() x0j = (np.r_[x0[1], h[1][:j]]).sum() x0k = (np.r_[x0[2], h[2][:k]]).sum() self.children[i][j][k] = TreeCell(self, x0=[x0i, x0j, x0k], depth=0, sz=[h[0][i], h[1][j], h[2][k]], fXm=fXm, fYm=fYm, fZm=fZm)
def getInitialFieldsDeriv(self, src, v, adjoint=False): if adjoint is False: if self._fieldType is 'b' or self._fieldType is 'j': ifieldsDeriv = np.zeros(self.mesh.nF) elif self._fieldType is 'e' or self._fieldType is 'h': ifieldsDeriv = np.zeros(self.mesh.nE) elif adjoint is True: ifieldsDeriv = np.zeros(self.mapping.nP) ifieldsDeriv = (Utils.mkvc( getattr(src, '{}InitialDeriv'.format(self._fieldType), None)(self, v, adjoint)) + ifieldsDeriv ) return ifieldsDeriv
def gettopoCC(mesh, airind): # def gettopoCC(mesh, airind): """ Get topography from active indices of mesh. """ mesh2D = Mesh.TensorMesh([mesh.hx, mesh.hy], mesh.x0[:2]) zc = mesh.gridCC[:,2] AIRIND = airind.reshape((mesh.vnC[0]*mesh.vnC[1],mesh.vnC[2]), order='F') ZC = zc.reshape((mesh.vnC[0]*mesh.vnC[1], mesh.vnC[2]), order='F') topo = np.zeros(ZC.shape[0]) topoCC = np.zeros(ZC.shape[0]) for i in range(ZC.shape[0]): ind = np.argmax(ZC[i,:][~AIRIND[i,:]]) topo[i] = ZC[i,:][~AIRIND[i,:]].max() + mesh.hz[~AIRIND[i,:]][ind]*0.5 topoCC[i] = ZC[i,:][~AIRIND[i,:]].max() XY = Utils.ndgrid(mesh.vectorCCx, mesh.vectorCCy) return mesh2D, topoCC
def getSourceTerm(self, tInd): Srcs = self.survey.srcList if self._eqLocs is 'FE': s_m = np.zeros((self.mesh.nF, len(Srcs))) s_e = np.zeros((self.mesh.nE, len(Srcs))) elif self._eqLocs is 'EF': s_m = np.zeros((self.mesh.nE, len(Srcs))) s_e = np.zeros((self.mesh.nF, len(Srcs))) for i, src in enumerate(Srcs): smi, sei = src.eval(self, self.times[tInd]) s_m[:, i] = s_m[:, i] + smi s_e[:, i] = s_e[:, i] + sei return s_m, s_e
def Jtvec(self, m, v, f=None): """ Sensitivity transpose times a vector """ if f is None: f = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): ftype = self._fieldType + 'Solution' u_src = f[src, ftype] for rx in src.rxList: PTv = rx.projectFieldsDeriv(src, self.mesh, f, v[src, rx], adjoint=True) # wrt u, need possibility wrt m df_duTFun = getattr(f, '_%sDeriv_u'%rx.projField, None) df_duT = df_duTFun(src, PTv, adjoint=True) if df_duT is not None: dA_duIT = ATinv * df_duT else: dA_duIT = ATinv * PTv dA_dmT = self.getADeriv_m(freq, u_src, dA_duIT, adjoint=True) dRHS_dmT = self.getRHSDeriv_m(src, dA_duIT, adjoint=True) if dRHS_dmT is None: du_dmT = - dA_dmT else: du_dmT = -dA_dmT + dRHS_dmT df_dmFun = getattr(f, '_%sDeriv_m'%rx.projField, None) dfT_dm = df_dmFun(src, PTv, adjoint=True) if dfT_dm is not None: du_dmT += dfT_dm real_or_imag = rx.projComp if real_or_imag == 'real': Jtv += du_dmT.real elif real_or_imag == 'imag': Jtv += - du_dmT.real else: raise Exception('Must be real or imag') return Jtv
def Jtvec(self, m, v, u=None): """ Function to calculate the transpose of the data sensitivities (dD/dm)^T times a vector. :param numpy.ndarray m (nC, 1) - conductive model :param numpy.ndarray v (nD, 1) - vector :param MTfields object u (optional) - MT fields object, if not given it is calculated :rtype: MTdata object :return: Data sensitivities wrt m """ if u is None: u = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): ftype = self._fieldType + 'Solution' u_src = u[src, :] for rx in src.rxList: # Get the adjoint evalDeriv # PTv needs to be nE, PTv = rx.evalDeriv(src, self.mesh, u, mkvc(v[src, rx],2), adjoint=True) # wrt u, need possibility wrt m # Get the dA_duIT = ATinv * PTv dA_dmT = self.getADeriv_m(freq, u_src, mkvc(dA_duIT), adjoint=True) dRHS_dmT = self.getRHSDeriv_m(freq, mkvc(dA_duIT), adjoint=True) # Make du_dmT if dRHS_dmT is None: du_dmT = -dA_dmT else: du_dmT = -dA_dmT + dRHS_dmT # Select the correct component # du_dmT needs to be of size nC, real_or_imag = rx.projComp if real_or_imag == 'real': Jtv += du_dmT.real elif real_or_imag == 'imag': Jtv += -du_dmT.real else: raise Exception('Must be real or imag') # Clean the factorization, clear memory. ATinv.clean() return Jtv
def DCfun(mesh, pts): D = mesh.faceDiv sigma = 1e-2*np.ones(mesh.nC) MsigI = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True) A = -D*MsigI*D.T A[-1,-1] /= mesh.vol[-1] # Remove null space rhs = np.zeros(mesh.nC) txind = Utils.meshutils.closestPoints(mesh, pts) rhs[txind] = np.r_[1,-1] return A, rhs
def DCfun(mesh, pts): D = mesh.faceDiv sigma = 1e-2 * np.ones(mesh.nC) MsigI = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True) A = -D * MsigI * D.T A[-1, -1] /= mesh.vol[-1] # Remove null space rhs = np.zeros(mesh.nC) txind = Utils.meshutils.closestPoints(mesh, pts) rhs[txind] = np.r_[1, -1] return A, rhs
def Jtvec(self, m, v, u=None): """ Sensitivity transpose times a vector :param numpy.array m: inversion model (nP,) :param numpy.array v: vector which we take adjoint product with (nP,) :param SimPEG.EM.FDEM.Fields u: fields object :rtype numpy.array: :return: Jv (ndata,) """ if u is None: u = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): u_src = u[src, self._solutionType] for rx in src.rxList: PTv = rx.evalDeriv(src, self.mesh, u, v[src, rx], adjoint=True) # wrt u, need possibility wrt m df_duTFun = getattr(u, '_%sDeriv'%rx.projField, None) df_duT, df_dmT = df_duTFun(src, None, PTv, adjoint=True) ATinvdf_duT = ATinv * df_duT dA_dmT = self.getADeriv(freq, u_src, ATinvdf_duT, adjoint=True) dRHS_dmT = self.getRHSDeriv(freq, src, ATinvdf_duT, adjoint=True) du_dmT = -dA_dmT + dRHS_dmT 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': Jtv += np.array(df_dmT, dtype=complex).real elif real_or_imag is 'imag': Jtv += - np.array(df_dmT, dtype=complex).real else: raise Exception('Must be real or imag') ATinv.clean() return Utils.mkvc(Jtv)
def getSrc_locs(DCsurvey): """ """ srcMat = np.zeros((DCsurvey.nSrc,2,3)) for ii in range(DCsurvey.nSrc): srcMat[ii,:,:] = np.asarray(DCsurvey.srcList[ii].loc) return srcMat
def getInitialFields(self): """ Ask the sources for initial fields """ Srcs = self.survey.srcList if self._fieldType in ['b', 'j']: ifields = np.zeros((self.mesh.nF, len(Srcs))) elif self._fieldType in ['e', 'h']: ifields = np.zeros((self.mesh.nE, len(Srcs))) for i, src in enumerate(Srcs): ifields[:, i] = ( ifields[:, i] + getattr( src, '{}Initial'.format(self._fieldType), None )(self) ) return ifields
def Jtvec(self, m, v, f=None): """ Sensitivity transpose times a vector :param numpy.array m: inversion model (nP,) :param numpy.array v: vector which we take adjoint product with (nP,) :param SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM u: fields object :rtype numpy.array: :return: Jv (ndata,) """ if f is None: f = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): u_src = f[src, self._solutionType] 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, '_{0}Deriv'.format(rx.projField), None) df_duT, df_dmT = df_duTFun(src, None, PTv, adjoint=True) ATinvdf_duT = ATinv * df_duT dA_dmT = self.getADeriv(freq, u_src, ATinvdf_duT, adjoint=True) dRHS_dmT = self.getRHSDeriv(freq, src, ATinvdf_duT, adjoint=True) du_dmT = -dA_dmT + dRHS_dmT df_dmT = df_dmT + du_dmT # TODO: this should be taken care of by the reciever? if rx.component is 'real': Jtv += np.array(df_dmT, dtype=complex).real elif rx.component is 'imag': Jtv += - np.array(df_dmT, dtype=complex).real else: raise Exception('Must be real or imag') ATinv.clean() return Utils.mkvc(Jtv)
def setUp(self): cs = 25. hx = [(cs,0, -1.3),(cs,21),(cs,0, 1.3)] hy = [(cs,0, -1.3),(cs,21),(cs,0, 1.3)] hz = [(cs,0, -1.3),(cs,20),(cs,0, 1.3)] mesh = Mesh.TensorMesh([hx, hy, hz],x0="CCC") blkind0 = Utils.ModelBuilder.getIndicesSphere(np.r_[-100., -100., -200.], 75., mesh.gridCC) blkind1 = Utils.ModelBuilder.getIndicesSphere(np.r_[100., 100., -200.], 75., mesh.gridCC) sigma = np.ones(mesh.nC)*1e-2 airind = mesh.gridCC[:,2]>0. sigma[airind] = 1e-8 eta = np.zeros(mesh.nC) tau = np.ones_like(sigma)*1. eta[blkind0] = 0.1 eta[blkind1] = 0.1 tau[blkind0] = 0.1 tau[blkind1] = 0.01 actmapeta = Maps.InjectActiveCells(mesh, ~airind, 0.) actmaptau = Maps.InjectActiveCells(mesh, ~airind, 1.) x = mesh.vectorCCx[(mesh.vectorCCx>-155.)&(mesh.vectorCCx<155.)] y = mesh.vectorCCx[(mesh.vectorCCy>-155.)&(mesh.vectorCCy<155.)] Aloc = np.r_[-200., 0., 0.] Bloc = np.r_[200., 0., 0.] M = Utils.ndgrid(x-25.,y, np.r_[0.]) N = Utils.ndgrid(x+25.,y, np.r_[0.]) times = np.arange(10)*1e-3 + 1e-3 rx = SIP.Rx.Dipole(M, N, times) src = SIP.Src.Dipole([rx], Aloc, Bloc) survey = SIP.Survey([src]) colemap = [("eta", Maps.IdentityMap(mesh)*actmapeta), ("taui", Maps.IdentityMap(mesh)*actmaptau)] problem = SIP.Problem3D_N(mesh, sigma=sigma, mapping=colemap) problem.Solver = Solver problem.pair(survey) mSynth = np.r_[eta[~airind], 1./tau[~airind]] survey.makeSyntheticData(mSynth) # Now set up the problem to do some minimization dmis = DataMisfit.l2_DataMisfit(survey) regmap = Maps.IdentityMap(nP=int(mSynth[~airind].size*2)) reg = SIP.MultiRegularization(mesh, mapping=regmap, nModels=2, indActive=~airind) opt = Optimization.InexactGaussNewton(maxIterLS=20, maxIter=10, tolF=1e-6, tolX=1e-6, tolG=1e-6, maxIterCG=6) invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4) inv = Inversion.BaseInversion(invProb) self.inv = inv self.reg = reg self.p = problem self.mesh = mesh self.m0 = mSynth self.survey = survey self.dmis = dmis
def readUBC_DC2DModel(fileName): from SimPEG import np, mkvc """ Read UBC GIF 2DTensor model and generate 2D Tensor model in simpeg Input: :param fileName, path to the UBC GIF 2D model file Output: :param SimPEG TensorMesh 2D object :return Created on Thu Nov 12 13:14:10 2015 @author: dominiquef """ # Open fileand skip header... assume that we know the mesh already obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') dim = np.array(obsfile[0].split(),dtype=float) temp = np.array(obsfile[1].split(),dtype=float) if len(temp) > 1: model = np.zeros(dim) for ii in range(len(obsfile)-1): mm = np.array(obsfile[ii+1].split(),dtype=float) model[:,ii] = mm model = model[:,::-1] else: if len(obsfile[1:])==1: mm = np.array(obsfile[1:].split(),dtype=float) else: mm = np.array(obsfile[1:],dtype=float) # Permute the second dimension to flip the order model = mm.reshape(dim[1],dim[0]) model = model[::-1,:] model = np.transpose(model, (1, 0)) model = mkvc(model) return model
def getSourceTerm(self, tInd): """ Assemble the source term. This ensures that the RHS is a vector / array of the correct size """ Srcs = self.survey.srcList if self._formulation == 'EB': s_m = np.zeros((self.mesh.nF, len(Srcs))) s_e = np.zeros((self.mesh.nE, len(Srcs))) elif self._formulation == 'HJ': s_m = np.zeros((self.mesh.nE, len(Srcs))) s_e = np.zeros((self.mesh.nF, len(Srcs))) for i, src in enumerate(Srcs): smi, sei = src.eval(self, self.times[tInd]) s_m[:, i] = s_m[:, i] + smi s_e[:, i] = s_e[:, i] + sei return s_m, s_e
def DCfun(mesh, pts): D = mesh.faceDiv G = D.T sigma = 1e-2 * np.ones(mesh.nC) Msigi = mesh.getFaceInnerProduct(1. / sigma) MsigI = Utils.sdInv(Msigi) A = D * MsigI * G A[-1, -1] /= mesh.vol[-1] # Remove null space rhs = np.zeros(mesh.nC) txind = Utils.meshutils.closestPoints(mesh, pts) rhs[txind] = np.r_[1, -1] return A, rhs
def DCfun(mesh, pts): D = mesh.faceDiv G = D.T sigma = 1e-2*np.ones(mesh.nC) Msigi = mesh.getFaceInnerProduct(1./sigma) MsigI = Utils.sdInv(Msigi) A = D*MsigI*G A[-1,-1] /= mesh.vol[-1] # Remove null space rhs = np.zeros(mesh.nC) txind = Utils.meshutils.closestPoints(mesh, pts) rhs[txind] = np.r_[1,-1] return A, rhs
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 readGravityObservations(self, obs_file): """ Read UBC grav file format INPUT: :param fileName, path to the UBC obs grav file OUTPUT: :param survey """ fid = open(obs_file, 'r') # First line has the number of rows line = fid.readline() ndat = np.array(line.split(), dtype=int) # Pre-allocate space for obsx, obsy, obsz, data, uncert line = fid.readline() temp = np.array(line.split(), dtype=float) d = np.zeros(ndat, dtype=float) wd = np.zeros(ndat, dtype=float) locXYZ = np.zeros((ndat[0], 3), dtype=float) for ii in range(ndat): temp = np.array(line.split(), dtype=float) locXYZ[ii, :] = temp[:3] d[ii] = temp[3] wd[ii] = temp[4] line = fid.readline() rxLoc = BaseGrav.RxObs(locXYZ) srcField = BaseGrav.SrcField([rxLoc]) survey = BaseGrav.LinearSurvey(srcField) survey.dobs = d survey.std = wd return survey
def readGravityObservations(self, obs_file): """ Read UBC grav file format INPUT: :param fileName, path to the UBC obs grav file OUTPUT: :param survey """ fid = open(obs_file,'r') # First line has the number of rows line = fid.readline() ndat = np.array(line.split(),dtype=int) # Pre-allocate space for obsx, obsy, obsz, data, uncert line = fid.readline() temp = np.array(line.split(),dtype=float) d = np.zeros(ndat, dtype=float) wd = np.zeros(ndat, dtype=float) locXYZ = np.zeros( (ndat,3), dtype=float) for ii in range(ndat): temp = np.array(line.split(),dtype=float) locXYZ[ii,:] = temp[:3] d[ii] = temp[3] wd[ii] = temp[4] line = fid.readline() rxLoc = BaseGrav.RxObs(locXYZ) srcField = BaseGrav.SrcField([rxLoc]) survey = BaseGrav.LinearSurvey(srcField) survey.dobs = d survey.std = wd return survey
def readUBC_DC2DModel(fileName): """ Read UBC GIF 2DTensor model and generate 2D Tensor model in simpeg Input: :param fileName, path to the UBC GIF 2D model file Output: :param SimPEG TensorMesh 2D object :return Created on Thu Nov 12 13:14:10 2015 @author: dominiquef """ from SimPEG import np, mkvc # Open fileand skip header... assume that we know the mesh already obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') dim = np.array(obsfile[0].split(),dtype=float) temp = np.array(obsfile[1].split(),dtype=float) if len(temp) > 1: model = np.zeros(dim) for ii in range(len(obsfile)-1): mm = np.array(obsfile[ii+1].split(),dtype=float) model[:,ii] = mm model = model[:,::-1] else: if len(obsfile[1:])==1: mm = np.array(obsfile[1:].split(),dtype=float) else: mm = np.array(obsfile[1:],dtype=float) # Permute the second dimension to flip the order model = mm.reshape(dim[1],dim[0]) model = model[::-1,:] model = np.transpose(model, (1, 0)) model = mkvc(model) return model
def Jtvec(self, m, v, u=None): if u is None: u = self.fields(m) self.curModel = m # Ensure v is a data object. if not isinstance(v, self.dataPair): v = self.dataPair(self.survey, v) Jtv = np.zeros(m.size) for freq in self.survey.freqs: AT = self.getA(freq).T ATinv = self.Solver(AT, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): ftype = self._fieldType + 'Solution' u_src = u[src, :] for rx in src.rxList: # Get the adjoint projectFieldsDeriv # PTv needs to be nE, PTv = rx.projectFieldsDeriv( src, self.mesh, u, mkvc(v[src, rx], 2), adjoint=True) # wrt u, need possibility wrt m # Get the dA_duIT = ATinv * PTv dA_dmT = self.getADeriv_m(freq, u_src, mkvc(dA_duIT), adjoint=True) dRHS_dmT = self.getRHSDeriv_m(freq, mkvc(dA_duIT), adjoint=True) # Make du_dmT if dRHS_dmT is None: du_dmT = -dA_dmT else: du_dmT = -dA_dmT + dRHS_dmT # Select the correct component # du_dmT needs to be of size nC, real_or_imag = rx.projComp if real_or_imag == 'real': Jtv += du_dmT.real elif real_or_imag == 'imag': Jtv += -du_dmT.real else: raise Exception('Must be real or imag') return Jtv
def getSourceTerm(self, freq): """ Evaluates the sources for a given frequency and puts them in matrix form :param float freq: Frequency :rtype: (numpy.ndarray, numpy.ndarray) :return: S_m, S_e (nE or nF, nSrc) """ Srcs = self.survey.getSrcByFreq(freq) if self._formulation is 'EB': S_m = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) S_e = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) elif self._formulation is 'HJ': S_m = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) S_e = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) for i, src in enumerate(Srcs): smi, sei = src.eval(self) S_m[:,i] = S_m[:,i] + smi S_e[:,i] = S_e[:,i] + sei return S_m, S_e
def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in ['F', 'E'], "projType must be 'F' for faces or 'E' for edges" tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) if tensorType == 0: Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC,1)) if not invMat and not invProp: dMdprop = self.dim * Av.T * V * ones elif invMat and invProp: dMdprop = self.dim * Utils.sdiag(MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag(1./prop**2) if tensorType == 1: Av = getattr(self, 'ave'+projType+'2CC') V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = self.dim * Av.T * V elif invMat and invProp: dMdprop = self.dim * Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2) if tensorType == 2: # anisotropic Av = getattr(self, 'ave'+projType+'2CCV') V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if not invMat and not invProp: dMdprop = Av.T * V elif invMat and invProp: dMdprop = Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2) if dMdprop is not None: def innerProductDeriv(v=None): if v is None: print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop' return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None
def getSourceTerm(self, freq): """ Evaluates the sources for a given frequency and puts them in matrix form :param float freq: Frequency :rtype: tuple :return: (s_m, s_e) (nE or nF, nSrc) """ Srcs = self.survey.getSrcByFreq(freq) if self._formulation is 'EB': s_m = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) s_e = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) elif self._formulation is 'HJ': s_m = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) s_e = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) for i, src in enumerate(Srcs): smi, sei = src.eval(self) #Why are you adding? s_m[:,i] = s_m[:,i] + smi s_e[:,i] = s_e[:,i] + sei return s_m, s_e
def getSourceTerm(self, freq): """ Evaluates the sources for a given frequency and puts them in matrix form :param float freq: Frequency :rtype: tuple :return: (s_m, s_e) (nE or nF, nSrc) """ Srcs = self.survey.getSrcByFreq(freq) if self._formulation is 'EB': s_m = np.zeros((self.mesh.nF, len(Srcs)), dtype=complex) s_e = np.zeros((self.mesh.nE, len(Srcs)), dtype=complex) elif self._formulation is 'HJ': s_m = np.zeros((self.mesh.nE, len(Srcs)), dtype=complex) s_e = np.zeros((self.mesh.nF, len(Srcs)), dtype=complex) for i, src in enumerate(Srcs): smi, sei = src.eval(self) #Why are you adding? s_m[:, i] = s_m[:, i] + smi s_e[:, i] = s_e[:, i] + sei return s_m, s_e
def getSourceTerm(self, freq): """ Evaluates the sources for a given frequency and puts them in matrix form :param float freq: Frequency :rtype: numpy.ndarray (nE or nF, nSrc) :return: S_m, S_e """ Srcs = self.survey.getSrcByFreq(freq) if self._eqLocs is 'FE': S_m = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) S_e = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) elif self._eqLocs is 'EF': S_m = np.zeros((self.mesh.nE,len(Srcs)), dtype=complex) S_e = np.zeros((self.mesh.nF,len(Srcs)), dtype=complex) for i, src in enumerate(Srcs): smi, sei = src.eval(self) if smi is not None: S_m[:,i] = Utils.mkvc(smi) if sei is not None: S_e[:,i] = Utils.mkvc(sei) return S_m, S_e
def appResNorm(sigmaHalf): nFreq = 26 m1d = Mesh.TensorMesh([[(100,5,1.5),(100.,10),(100,5,1.5)]], x0=['C']) sigma = np.zeros(m1d.nC) + sigmaHalf sigma[m1d.gridCC[:]>200] = 1e-8 # Calculate the analytic fields freqs = np.logspace(4,-4,nFreq) Z = [] for freq in freqs: Ed, Eu, Hd, Hu = NSEM.Utils.getEHfields(m1d,sigma,freq,np.array([200])) Z.append((Ed + Eu)/(Hd + Hu)) Zarr = np.concatenate(Z) app_r, app_p = NSEM.Utils.appResPhs(freqs,Zarr) return np.linalg.norm(np.abs(app_r - np.ones(nFreq)/sigmaHalf)) / np.log10(sigmaHalf)
def __init__(self, h_in, x0_in=None): assert type(h_in) in [list, tuple], 'h_in must be a list' assert len(h_in) in [1, 2, 3], 'h_in must be of dimension 1, 2, or 3' h = list(range(len(h_in))) for i, h_i in enumerate(h_in): if Utils.isScalar(h_i) and type(h_i) is not np.ndarray: # This gives you something over the unit cube. h_i = self._unitDimensions[i] * np.ones(int(h_i)) / int(h_i) elif type(h_i) is list: h_i = Utils.meshTensor(h_i) assert isinstance( h_i, np.ndarray), ("h[{0:d}] is not a numpy array.".format(i)) assert len(h_i.shape) == 1, ( "h[{0:d}] must be a 1D numpy array.".format(i)) h[i] = h_i[:] # make a copy. x0 = np.zeros(len(h)) if x0_in is not None: assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)" for i in range(len(h)): x_i, h_i = x0_in[i], h[i] if Utils.isScalar(x_i): x0[i] = x_i elif x_i == '0': x0[i] = 0.0 elif x_i == 'C': x0[i] = -h_i.sum() * 0.5 elif x_i == 'N': x0[i] = -h_i.sum() else: raise Exception( "x0[{0:d}] must be a scalar or '0' to be zero, " "'C' to center, or 'N' to be negative.".format(i)) if isinstance(self, BaseRectangularMesh): BaseRectangularMesh.__init__(self, np.array([x.size for x in h]), x0) else: BaseMesh.__init__(self, np.array([x.size for x in h]), x0) # Ensure h contains 1D vectors self._h = [Utils.mkvc(x.astype(float)) for x in h]
def getInitialFields(self, mesh): """Vertical magnetic dipole, magnetic vector potential""" if self.waveformType == "STEPOFF": print ">> Step waveform: Non-zero initial condition" if mesh._meshType is 'CYL': if mesh.isSymmetric: MVP = MagneticDipoleVectorPotential(self.loc, mesh, 'Ey') else: raise NotImplementedError( 'Non-symmetric cyl mesh not implemented yet!') elif mesh._meshType is 'TENSOR': MVP = MagneticDipoleVectorPotential(self.loc, mesh, ['Ex', 'Ey', 'Ez']) else: raise Exception('Unknown mesh for VMD') return {"b": mesh.edgeCurl * MVP} elif self.waveformType == "GENERAL": print ">> General waveform: Zero initial condition" return {"b": np.zeros(mesh.nF)} else: raise NotImplementedError("Only use STEPOFF or GENERAL")
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 gen_DCIPsurvey(endl, mesh, stype, a, b, n): """ Load in endpoints and survey specifications to generate Tx, Rx location stations. Assumes flat topo for now... Input: :param endl -> input endpoints [x1, y1, z1, x2, y2, z2] :object mesh -> SimPEG mesh object :switch stype -> "dpdp" (dipole-dipole) | "pdp" (pole-dipole) | 'gradient' : param a, n -> pole seperation, number of rx dipoles per tx Output: :param Tx, Rx -> List objects for each tx location Lines: P1x, P1y, P1z, P2x, P2y, P2z Created on Wed December 9th, 2015 @author: dominiquef !! Require clean up to deal with DCsurvey """ from SimPEG import np def xy_2_r(x1, x2, y1, y2): r = np.sqrt(np.sum((x2 - x1)**2 + (y2 - y1)**2)) return r ## Evenly distribute electrodes and put on surface # Mesure survey length and direction dl_len = xy_2_r(endl[0, 0], endl[1, 0], endl[0, 1], endl[1, 1]) dl_x = (endl[1, 0] - endl[0, 0]) / dl_len dl_y = (endl[1, 1] - endl[0, 1]) / dl_len nstn = np.floor(dl_len / a) # Compute discrete pole location along line stn_x = endl[0, 0] + np.array(range(int(nstn))) * dl_x * a stn_y = endl[0, 1] + np.array(range(int(nstn))) * dl_y * a if mesh.dim == 2: ztop = mesh.vectorNy[-1] # Create line of P1 locations M = np.c_[stn_x, np.ones(nstn).T * ztop] # Create line of P2 locations N = np.c_[stn_x + a * dl_x, np.ones(nstn).T * ztop] elif mesh.dim == 3: ztop = mesh.vectorNz[-1] # Create line of P1 locations M = np.c_[stn_x, stn_y, np.ones(nstn).T * ztop] # Create line of P2 locations N = np.c_[stn_x + a * dl_x, stn_y + a * dl_y, np.ones(nstn).T * ztop] ## Build list of Tx-Rx locations depending on survey type # Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn] # Pole-dipole: Moving pole on one end -> [A a MN1 a MN2 ... MNn a B] SrcList = [] if stype != 'gradient': for ii in range(0, int(nstn) - 1): if stype == 'dipole-dipole': tx = np.c_[M[ii, :], N[ii, :]] elif stype == 'pole-dipole': tx = np.c_[M[ii, :], M[ii, :]] else: raise Exception( 'The stype must be "dipole-dipole" or "pole-dipole"') # Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]]) # Current elctrode seperation AB = xy_2_r(tx[0, 1], endl[1, 0], tx[1, 1], endl[1, 1]) # Number of receivers to fit nstn = np.min([np.floor((AB - b) / a), n]) # Check if there is enough space, else break the loop if nstn <= 0: continue # Compute discrete pole location along line stn_x = N[ii, 0] + dl_x * b + np.array(range(int(nstn))) * dl_x * a stn_y = N[ii, 1] + dl_y * b + np.array(range(int(nstn))) * dl_y * a # Create receiver poles if mesh.dim == 3: # Create line of P1 locations P1 = np.c_[stn_x, stn_y, np.ones(nstn).T * ztop] # Create line of P2 locations P2 = np.c_[stn_x + a * dl_x, stn_y + a * dl_y, np.ones(nstn).T * ztop] rxClass = DC.Rx.Dipole(P1, P2) elif mesh.dim == 2: # Create line of P1 locations P1 = np.c_[stn_x, np.ones(nstn).T * ztop] # Create line of P2 locations P2 = np.c_[stn_x + a * dl_x, np.ones(nstn).T * ztop] rxClass = DC.Rx.Dipole_ky(P1, P2) if stype == 'dipole-dipole': srcClass = DC.Src.Dipole([rxClass], M[ii, :], N[ii, :]) elif stype == 'pole-dipole': srcClass = DC.Src.Pole([rxClass], M[ii, :]) SrcList.append(srcClass) elif stype == 'gradient': # Gradient survey only requires Tx at end of line and creates a square # grid of receivers at in the middle at a pre-set minimum distance # Get the edge limit of survey area min_x = endl[0, 0] + dl_x * b min_y = endl[0, 1] + dl_y * b max_x = endl[1, 0] - dl_x * b max_y = endl[1, 1] - dl_y * b box_l = np.sqrt((min_x - max_x)**2 + (min_y - max_y)**2) box_w = box_l / 2. nstn = np.floor(box_l / a) # Compute discrete pole location along line stn_x = min_x + np.array(range(int(nstn))) * dl_x * a stn_y = min_y + np.array(range(int(nstn))) * dl_y * a # Define number of cross lines nlin = int(np.floor(box_w / a)) lind = range(-nlin, nlin + 1) ngrad = nstn * len(lind) rx = np.zeros([ngrad, 6]) for ii in range(len(lind)): # Move line in perpendicular direction by dipole spacing lxx = stn_x - lind[ii] * a * dl_y lyy = stn_y + lind[ii] * a * dl_x M = np.c_[lxx, lyy, np.ones(nstn).T * ztop] N = np.c_[lxx + a * dl_x, lyy + a * dl_y, np.ones(nstn).T * ztop] rx[(ii * nstn):((ii + 1) * nstn), :] = np.c_[M, N] if mesh.dim == 3: rxClass = DC.Rx.Dipole(rx[:, :3], rx[:, 3:]) elif mesh.dim == 2: M = M[:, [0, 2]] N = N[:, [0, 2]] rxClass = DC.Rx.Dipole_ky(rx[:, [0, 2]], rx[:, [3, 5]]) srcClass = DC.Src.Dipole([rxClass], M[0, :], N[-1, :]) SrcList.append(srcClass) else: print """stype must be either 'pole-dipole', 'dipole-dipole' or 'gradient'. """ return SrcList
def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False): """ :param str projType: 'E' or 'F' :param TensorType tensorType: type of the tensor :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :rtype: function :return: dMdmu, the derivative of the inner product matrix """ assert projType in [ 'F', 'E' ], "projType must be 'F' for faces or 'E' for edges" tensorType = Utils.TensorType(self, prop) dMdprop = None if invMat: MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat) if tensorType == 0: Av = getattr(self, 'ave' + projType + '2CC') V = Utils.sdiag(self.vol) ones = sp.csr_matrix( (np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC, 1)) if not invMat and not invProp: dMdprop = self.dim * Av.T * V * ones elif invMat and invProp: dMdprop = self.dim * Utils.sdiag( MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag( 1. / prop**2) if tensorType == 1: Av = getattr(self, 'ave' + projType + '2CC') V = Utils.sdiag(self.vol) if not invMat and not invProp: dMdprop = self.dim * Av.T * V elif invMat and invProp: dMdprop = self.dim * Utils.sdiag( MI.diagonal()**2) * Av.T * V * Utils.sdiag(1. / prop**2) if tensorType == 2: # anisotropic Av = getattr(self, 'ave' + projType + '2CCV') V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol)) if not invMat and not invProp: dMdprop = Av.T * V elif invMat and invProp: dMdprop = Utils.sdiag(MI.diagonal()** 2) * Av.T * V * Utils.sdiag(1. / prop**2) if dMdprop is not None: def innerProductDeriv(v=None): if v is None: print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop' return dMdprop return Utils.sdiag(v) * dMdprop return innerProductDeriv else: return None