def fget(self): if(self._area is None or self._normals is None): # Compute areas of cell faces if(self.dim == 2): xy = self.gridN A, B = Utils.indexCube('AB', self.vnC+1, np.array([self.nNx, self.nCy])) edge1 = xy[B, :] - xy[A, :] normal1 = np.c_[edge1[:, 1], -edge1[:, 0]] area1 = length2D(edge1) A, D = Utils.indexCube('AD', self.vnC+1, np.array([self.nCx, self.nNy])) # Note that we are doing A-D to make sure the normal points the right way. # Think about it. Look at the picture. Normal points towards C iff you do this. edge2 = xy[A, :] - xy[D, :] normal2 = np.c_[edge2[:, 1], -edge2[:, 0]] area2 = length2D(edge2) self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2)] self._normals = [normalize2D(normal1), normalize2D(normal2)] elif(self.dim == 3): A, E, F, B = Utils.indexCube('AEFB', self.vnC+1, np.array([self.nNx, self.nCy, self.nCz])) normal1, area1 = Utils.faceInfo(self.gridN, A, E, F, B, average=False, normalizeNormals=False) A, D, H, E = Utils.indexCube('ADHE', self.vnC+1, np.array([self.nCx, self.nNy, self.nCz])) normal2, area2 = Utils.faceInfo(self.gridN, A, D, H, E, average=False, normalizeNormals=False) A, B, C, D = Utils.indexCube('ABCD', self.vnC+1, np.array([self.nCx, self.nCy, self.nNz])) normal3, area3 = Utils.faceInfo(self.gridN, A, B, C, D, average=False, normalizeNormals=False) self._area = np.r_[Utils.mkvc(area1), Utils.mkvc(area2), Utils.mkvc(area3)] self._normals = [normal1, normal2, normal3] return self._area
def plotGrid(self, ax=None, text=False, centers=False, faces=False, edges=False, lines=True, nodes=False, showIt=False): self.number() axOpts = {'projection':'3d'} if self.dim == 3 else {} if ax is None: ax = plt.subplot(111, **axOpts) if lines: [f.plotGrid(ax, text=text) for f in self.faces] if centers: [c.plotGrid(ax, text=text) for c in self.cells] if faces: fX = np.array([f.center for f in self.sortedFaceX]) ax.plot(fX[:,0],fX[:,1],'g>') fY = np.array([f.center for f in self.sortedFaceY]) ax.plot(fY[:,0],fY[:,1],'g^') if edges: eX = np.array([e.center for e in self.sortedFaceY]) ax.plot(eX[:,0],eX[:,1],'c>') eY = np.array([e.center for e in self.sortedFaceX]) ax.plot(eY[:,0],eY[:,1],'c^') if nodes: ns = np.array([n.x0 for n in self.sortedNodes]) ax.plot(ns[:,0],ns[:,1],'bs') ax.set_xlim((self.x0[0], self.h[0].sum())) ax.set_ylim((self.x0[1], self.h[1].sum())) if self.dim == 3: ax.set_zlim((self.x0[2], self.h[2].sum())) ax.grid(True) ax.hold(False) ax.set_xlabel('x1') ax.set_ylabel('x2') if showIt: plt.show()
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 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 test_ndgrid_2D(self): XY = ndgrid([self.a, self.b]) X1_test = np.array([1, 2, 3, 1, 2, 3]) X2_test = np.array([1, 1, 1, 2, 2, 2]) self.assertTrue(np.all(XY[:, 0] == X1_test)) self.assertTrue(np.all(XY[:, 1] == X2_test))
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 __init__(self, rxList, freq, S_m, integrate = True, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None): self._S_m = np.array(S_m,dtype=complex) self.freq = float(freq) self.integrate = integrate self._ePrimary = np.array(ePrimary,dtype=complex) self._bPrimary = np.array(bPrimary,dtype=complex) self._hPrimary = np.array(hPrimary,dtype=complex) self._jPrimary = np.array(jPrimary,dtype=complex) SrcFDEM.__init__(self, rxList)
def test_ndgrid_3D(self): XYZ = ndgrid([self.a, self.b, self.c]) X1_test = np.array([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]) X2_test = np.array([1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2]) X3_test = np.array([1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4]) self.assertTrue(np.all(XYZ[:, 0] == X1_test)) self.assertTrue(np.all(XYZ[:, 1] == X2_test)) self.assertTrue(np.all(XYZ[:, 2] == X3_test))
def halfSpaceProblemAnaVMDDiff(showIt=False, waveformType="STEPOFF"): cs, ncx, ncz, npad = 20., 25, 25, 15 hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') sighalf = 1e-2 siginf = np.ones(mesh.nC) * 1e-8 siginf[mesh.gridCC[:, -1] < 0.] = sighalf eta = np.ones(mesh.nC) * 0.2 tau = np.ones(mesh.nC) * 0.005 c = np.ones(mesh.nC) * 0.7 m = np.r_[siginf, eta, tau, c] iMap = Maps.IdentityMap(nP=int(mesh.nC)) maps = [('sigmaInf', iMap), ('eta', iMap), ('tau', iMap), ('c', iMap)] prb = ProblemATEMIP_b(mesh, mapping=maps) if waveformType == "GENERAL": # timeon = np.cumsum(np.r_[np.ones(10)*1e-3, np.ones(10)*5e-4, np.ones(10)*1e-4]) timeon = np.cumsum(np.r_[np.ones(10) * 1e-3, np.ones(10) * 5e-4, np.ones(10) * 1e-4]) timeon -= timeon.max() timeoff = np.cumsum(np.r_[np.ones(20) * 1e-5, np.ones(20) * 1e-4, np.ones(20) * 1e-3]) time = np.r_[timeon, timeoff] current_on = np.ones_like(timeon) current_on[[0, -1]] = 0. current = np.r_[current_on, np.zeros_like(timeoff)] wave = np.c_[time, current] prb.waveformType = "GENERAL" prb.currentwaveform(wave) prb.t0 = time.min() elif waveformType == "STEPOFF": prb.timeSteps = [(1e-5, 20), (1e-4, 20), (1e-3, 10)] offset = 20. tobs = np.logspace(-4, -2, 21) rx = EM.TDEM.RxTDEM(np.array([[offset, 0., 0.]]), tobs, "bz") src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([[0., 0., 0.]]), waveformType=waveformType) survey = EM.TDEM.SurveyTDEM([src]) prb.Solver = MumpsSolver prb.pair(survey) out = survey.dpred(m) bz_ana = mu_0 * hzAnalyticDipoleT_CC( offset, rx.times, sigmaInf=sighalf, eta=eta[0], tau=tau[0], c=c[0]) err = np.linalg.norm(bz_ana - out) / np.linalg.norm(bz_ana) print '>> Relative error = ', err if showIt: plt.loglog(rx.times, abs(bz_ana), 'k') plt.loglog(rx.times, abs(out), 'b.') plt.show() return err
def readUBC_DC2DLoc(fileName): from SimPEG import np """ Read UBC GIF 2D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 2D model file Output: :param rx, tx :return Created on Thu Nov 12 13:14:10 2015 @author: dominiquef """ # Open fileand skip header... assume that we know the mesh already #============================================================================== # fopen = open(fileName,'r') # lines = fopen.readlines() # fopen.close() #============================================================================== # Load file obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') # Check first line and figure out if 2D or 3D file format line = np.array(obsfile[0].split(),dtype=float) tx_A = [] tx_B = [] rx_M = [] rx_N = [] d = [] wd = [] for ii in range(obsfile.shape[0]): # If len==3, then simple format where tx-rx is listed on each line if len(line) == 4: temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') tx_A = np.hstack((tx_A,temp[0])) tx_B = np.hstack((tx_B,temp[1])) rx_M = np.hstack((rx_M,temp[2])) rx_N = np.hstack((rx_N,temp[3])) rx = np.transpose(np.array((rx_M,rx_N))) tx = np.transpose(np.array((tx_A,tx_B))) return tx, rx, d, wd
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 test_indexCube_3D(self): nN = np.array([3, 3, 3]) self.assertTrue( np.all( indexCube('A', nN) == np.array([0, 1, 3, 4, 9, 10, 12, 13]))) self.assertTrue( np.all( indexCube('B', nN) == np.array([3, 4, 6, 7, 12, 13, 15, 16]))) self.assertTrue( np.all( indexCube('C', nN) == np.array([4, 5, 7, 8, 13, 14, 16, 17]))) self.assertTrue( np.all( indexCube('D', nN) == np.array([1, 2, 4, 5, 10, 11, 13, 14]))) self.assertTrue( np.all( indexCube('E', nN) == np.array([9, 10, 12, 13, 18, 19, 21, 22 ]))) self.assertTrue( np.all( indexCube('F', nN) == np.array( [12, 13, 15, 16, 21, 22, 24, 25]))) self.assertTrue( np.all( indexCube('G', nN) == np.array( [13, 14, 16, 17, 22, 23, 25, 26]))) self.assertTrue( np.all( indexCube('H', nN) == np.array( [10, 11, 13, 14, 19, 20, 22, 23])))
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 toRecArray(self,returnType='RealImag'): ''' Function that returns a numpy.recarray for a SimpegMT impedance data object. :param str returnType: Switches between returning a rec array where the impedance is split to real and imaginary ('RealImag') or is a complex ('Complex') ''' # Define the record fields dtRI = [('freq',float),('x',float),('y',float),('z',float),('zxxr',float),('zxxi',float),('zxyr',float),('zxyi',float), ('zyxr',float),('zyxi',float),('zyyr',float),('zyyi',float),('tzxr',float),('tzxi',float),('tzyr',float),('tzyi',float)] dtCP = [('freq',float),('x',float),('y',float),('z',float),('zxx',complex),('zxy',complex),('zyx',complex),('zyy',complex),('tzx',complex),('tzy',complex)] impList = ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi'] for src in self.survey.srcList: # Temp array for all the receivers of the source. # Note: needs to be written more generally, using diffterent rxTypes and not all the data at the locaitons # Assume the same locs for all RX locs = src.rxList[0].locs if locs.shape[1] == 1: locs = np.hstack((np.array([[0.0,0.0]]),locs)) elif locs.shape[1] == 2: locs = np.hstack((np.array([[0.0]]),locs)) tArrRec = np.concatenate((src.freq*np.ones((locs.shape[0],1)),locs,np.nan*np.ones((locs.shape[0],12))),axis=1).view(dtRI) # np.array([(src.freq,rx.locs[0,0],rx.locs[0,1],rx.locs[0,2],np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ) for rx in src.rxList],dtype=dtRI) # Get the type and the value for the DataMT object as a list typeList = [[rx.rxType.replace('z1d','zyx'),self[src,rx]] for rx in src.rxList] # Insert the values to the temp array for nr,(key,val) in enumerate(typeList): tArrRec[key] = mkvc(val,2) # Masked array mArrRec = np.ma.MaskedArray(rec2ndarr(tArrRec),mask=np.isnan(rec2ndarr(tArrRec))).view(dtype=tArrRec.dtype) # Unique freq and loc of the masked array uniFLmarr = np.unique(mArrRec[['freq','x','y','z']]).copy() try: outTemp = recFunc.stack_arrays((outTemp,mArrRec)) #outTemp = np.concatenate((outTemp,dataBlock),axis=0) except NameError as e: outTemp = mArrRec if 'RealImag' in returnType: outArr = outTemp elif 'Complex' in returnType: # Add the real and imaginary to a complex number outArr = np.empty(outTemp.shape,dtype=dtCP) for comp in ['freq','x','y','z']: outArr[comp] = outTemp[comp].copy() for comp in ['zxx','zxy','zyx','zyy','tzx','tzy']: outArr[comp] = outTemp[comp+'r'].copy() + 1j*outTemp[comp+'i'].copy() else: raise NotImplementedError('{:s} is not implemented, as to be RealImag or Complex.') # Return return outArr
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 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 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 halfSpaceProblemAnaVMDDiff(showIt=False, waveformType="STEPOFF"): cs, ncx, ncz, npad = 20., 25, 25, 15 hx = [(cs, ncx), (cs, npad, 1.3)] hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)] mesh = Mesh.CylMesh([hx, 1, hz], '00C') prb = ProblemATEM_b(mesh) if waveformType == "GENERAL": timeon = np.cumsum(np.r_[np.ones(10) * 1e-3, np.ones(10) * 5e-4, np.ones(10) * 1e-4]) timeon -= timeon.max() timeoff = np.cumsum(np.r_[np.ones(10) * 5e-5, np.ones(10) * 1e-4, np.ones(10) * 5e-4, np.ones(10) * 1e-3, np.ones(10) * 5e-3]) time = np.r_[timeon, timeoff] current_on = np.ones_like(timeon) current_on[[0, -1]] = 0. current = np.r_[current_on, np.zeros_like(timeoff)] wave = np.c_[time, current] prb.waveformType = "GENERAL" prb.currentwaveform(wave) prb.t0 = time.min() elif waveformType == "STEPOFF": prb.timeSteps = [(1e-5, 10), (5e-5, 10), (1e-4, 10), (5e-4, 10), (1e-3, 10), (5e-3, 10)] offset = 20. tobs = np.logspace(-4, -2, 21) rx = EM.TDEM.RxTDEM(np.array([[offset, 0., 0.]]), tobs, "bz") src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([[0., 0., 0.]]), waveformType=waveformType) survey = EM.TDEM.SurveyTDEM([src]) prb.Solver = MumpsSolver sigma = np.ones(mesh.nC) * 1e-8 active = mesh.gridCC[:, 2] < 0. sig_half = 1e-2 sigma[active] = sig_half prb.pair(survey) out = survey.dpred(sigma) bz_ana = mu_0 * hzAnalyticDipoleT(offset, rx.times, sig_half) err = np.linalg.norm(bz_ana - out) / np.linalg.norm(bz_ana) print '>> Relative error = ', err if showIt: plt.loglog(rx.times, bz_ana, 'k') plt.loglog(rx.times, out, 'b.') plt.show() return err
def test_indexCube_3D(self): nN = np.array([3, 3, 3]) self.assertTrue(np.all(indexCube('A', nN) == np.array([0, 1, 3, 4, 9, 10, 12, 13]))) self.assertTrue(np.all(indexCube('B', nN) == np.array([3, 4, 6, 7, 12, 13, 15, 16]))) self.assertTrue(np.all(indexCube('C', nN) == np.array([4, 5, 7, 8, 13, 14, 16, 17]))) self.assertTrue(np.all(indexCube('D', nN) == np.array([1, 2, 4, 5, 10, 11, 13, 14]))) self.assertTrue(np.all(indexCube('E', nN) == np.array([9, 10, 12, 13, 18, 19, 21, 22]))) self.assertTrue(np.all(indexCube('F', nN) == np.array([12, 13, 15, 16, 21, 22, 24, 25]))) self.assertTrue(np.all(indexCube('G', nN) == np.array([13, 14, 16, 17, 22, 23, 25, 26]))) self.assertTrue(np.all(indexCube('H', nN) == np.array([10, 11, 13, 14, 19, 20, 22, 23])))
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) 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(f, '_%sDeriv_m'%rx.projField, None) dfT_dm = df_dmFun(src, PTv, adjoint=True) du_dmT += dfT_dm 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') return Jtv
def readUBC_DC2Dobs(fileName): """ ------- NEEDS TO BE UPDATED ------ Read UBC GIF 2D observation file and generate arrays for tx-rx location Input: :param fileName, path to the UBC GIF 2D model file Output: :param rx, tx :return Created on Thu Nov 12 13:14:10 2015 @author: dominiquef """ from SimPEG import np # Load file obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!') # Check first line and figure out if 2D or 3D file format line = np.array(obsfile[0].split(),dtype=float) tx_A = [] tx_B = [] rx_M = [] rx_N = [] d = [] wd = [] for ii in range(obsfile.shape[0]): # If len==3, then simple format where tx-rx is listed on each line if len(line) == 4: temp = np.fromstring(obsfile[ii], dtype=float,sep=' ') tx_A = np.hstack((tx_A,temp[0])) tx_B = np.hstack((tx_B,temp[1])) rx_M = np.hstack((rx_M,temp[2])) rx_N = np.hstack((rx_N,temp[3])) rx = np.transpose(np.array((rx_M,rx_N))) tx = np.transpose(np.array((tx_A,tx_B))) return tx, rx, d, wd
def halfSpaceProblemAnaVMDDiff(showIt=False, waveformType="STEPOFF"): cs, ncx, ncz, npad = 20., 25, 25, 15 hx = [(cs,ncx), (cs,npad,1.3)] hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] mesh = Mesh.CylMesh([hx,1,hz], '00C') sighalf = 1e-2 siginf = np.ones(mesh.nC)*1e-8 siginf[mesh.gridCC[:,-1]<0.] = sighalf eta = np.ones(mesh.nC)*0.2 tau = np.ones(mesh.nC)*0.005 c = np.ones(mesh.nC)*0.7 m = np.r_[siginf, eta, tau, c] iMap = Maps.IdentityMap(nP=int(mesh.nC)) maps = [('sigmaInf', iMap), ('eta', iMap), ('tau', iMap), ('c', iMap)] prb = ProblemATEMIP_b(mesh, mapping = maps) if waveformType =="GENERAL": # timeon = np.cumsum(np.r_[np.ones(10)*1e-3, np.ones(10)*5e-4, np.ones(10)*1e-4]) timeon = np.cumsum(np.r_[np.ones(10)*1e-3, np.ones(10)*5e-4, np.ones(10)*1e-4]) timeon -= timeon.max() timeoff = np.cumsum(np.r_[np.ones(20)*1e-5, np.ones(20)*1e-4, np.ones(20)*1e-3]) time = np.r_[timeon, timeoff] current_on = np.ones_like(timeon) current_on[[0,-1]] = 0. current = np.r_[current_on, np.zeros_like(timeoff)] wave = np.c_[time, current] prb.waveformType = "GENERAL" prb.currentwaveform(wave) prb.t0 = time.min() elif waveformType =="STEPOFF": prb.timeSteps = [(1e-5, 20), (1e-4, 20), (1e-3, 10)] offset = 20. tobs = np.logspace(-4, -2, 21) rx = EM.TDEM.RxTDEM(np.array([[offset, 0., 0.]]), tobs, "bz") src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([[0., 0., 0.]]), waveformType=waveformType) survey = EM.TDEM.SurveyTDEM([src]) prb.Solver = MumpsSolver prb.pair(survey) out = survey.dpred(m) bz_ana = mu_0*hzAnalyticDipoleT_CC(offset, rx.times, sigmaInf=sighalf, eta=eta[0], tau=tau[0], c=c[0]) err = np.linalg.norm(bz_ana-out)/np.linalg.norm(bz_ana) print '>> Relative error = ', err if showIt: plt.loglog(rx.times, abs(bz_ana), 'k') plt.loglog(rx.times, abs(out), 'b.') plt.show() return err
def edge(self): self.number() if self.dim == 2: edges = self.sortedFaceY + self.sortedFaceX elif self.dim == 3: edges = self.sortedEdgeX + self.sortedEdgeY + self.sortedEdgeZ return np.array([e.length for e in edges], dtype=float)
def __init__( self, rxList, freq, s_m, **kwargs ): # ePrimary=Zero(), bPrimary=Zero(), hPrimary=Zero(), jPrimary=Zero()): self._s_m = np.array(s_m, dtype=complex) self.freq = float(freq) BaseSrc.__init__(self, rxList, **kwargs)
def __init__( self, rxList, freq, s_m, **kwargs ): #ePrimary=Zero(), bPrimary=Zero(), hPrimary=Zero(), jPrimary=Zero()): self._s_m = np.array(s_m, dtype=complex) self.freq = float(freq) BaseSrc.__init__(self, rxList, **kwargs)
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 test_ana_boundary_computation(self): hxind = [(0, 25, 1.3), (21, 12.5), (0, 25, 1.3)] hyind = [(0, 25, 1.3), (21, 12.5), (0, 25, 1.3)] hzind = [(0, 25, 1.3), (20, 12.5), (0, 25, 1.3)] # hx, hy, hz = Utils.meshTensors(hxind, hyind, hzind) M3 = Mesh.TensorMesh([hxind, hyind, hzind], "CCC") indxd, indxu, indyd, indyu, indzd, indzu = M3.faceBoundaryInd mu0 = 4*np.pi*1e-7 chibkg = 0. chiblk = 0.01 chi = np.ones(M3.nC)*chibkg sph_ind = PF.MagAnalytics.spheremodel(M3, 0, 0, 0, 100) chi[sph_ind] = chiblk mu = (1.+chi)*mu0 Bbc, const = PF.MagAnalytics.CongruousMagBC(M3, np.array([1., 0., 0.]), chi) flag = 'secondary' Box = 1. H0 = Box/mu_0 Bbcxx, Bbcxy, Bbcxz = PF.MagAnalytics.MagSphereAnaFun(M3.gridFx[(indxd|indxu),0], M3.gridFx[(indxd|indxu),1], M3.gridFx[(indxd|indxu),2], 100, 0., 0., 0., mu_0, mu_0*(1+chiblk), H0, flag) Bbcyx, Bbcyy, Bbcyz = PF.MagAnalytics.MagSphereAnaFun(M3.gridFy[(indyd|indyu),0], M3.gridFy[(indyd|indyu),1], M3.gridFy[(indyd|indyu),2], 100, 0., 0., 0., mu_0, mu_0*(1+chiblk), H0, flag) Bbczx, Bbczy, Bbczz = PF.MagAnalytics.MagSphereAnaFun(M3.gridFz[(indzd|indzu),0], M3.gridFz[(indzd|indzu),1], M3.gridFz[(indzd|indzu),2], 100, 0., 0., 0., mu_0, mu_0*(1+chiblk), H0, flag) Bbc_ana = np.r_[Bbcxx, Bbcyy, Bbczz] if plotIt: import matplotlib.pyplot as plt fig, ax = plt.subplots(1,1, figsize = (10, 10)) ax.plot(Bbc_ana) ax.plot(Bbc) plt.show() err = np.linalg.norm(Bbc-Bbc_ana) / np.linalg.norm(Bbc_ana) assert err < 0.1, 'Mag Boundary computation is wrong!!, err = {}'.format(err)
def __init__(self, rxList, freq, S_e, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None): self._S_e = np.array(S_e,dtype=complex) self._ePrimary = ePrimary self._bPrimary = bPrimary self._hPrimary = hPrimary self._jPrimary = jPrimary self.freq = float(freq) SrcFDEM.__init__(self, rxList)
def test_ndgrid_3D(self): XYZ = ndgrid([self.a, self.b, self.c]) X1_test = np.array([ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3 ]) X2_test = np.array([ 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 ]) X3_test = np.array([ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4 ]) self.assertTrue(np.all(XYZ[:, 0] == X1_test)) self.assertTrue(np.all(XYZ[:, 1] == X2_test)) self.assertTrue(np.all(XYZ[:, 2] == X3_test))
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 halfSpaceProblemAnaVMDDiff(showIt=False, waveformType="STEPOFF"): cs, ncx, ncz, npad = 20., 25, 25, 15 hx = [(cs,ncx), (cs,npad,1.3)] hz = [(cs,npad,-1.3), (cs,ncz), (cs,npad,1.3)] mesh = Mesh.CylMesh([hx,1,hz], '00C') prb = ProblemATEM_b(mesh) if waveformType =="GENERAL": timeon = np.cumsum(np.r_[np.ones(10)*1e-3, np.ones(10)*5e-4, np.ones(10)*1e-4]) timeon -= timeon.max() timeoff = np.cumsum(np.r_[np.ones(10)*5e-5, np.ones(10)*1e-4, np.ones(10)*5e-4, np.ones(10)*1e-3, np.ones(10)*5e-3]) time = np.r_[timeon, timeoff] current_on = np.ones_like(timeon) current_on[[0,-1]] = 0. current = np.r_[current_on, np.zeros_like(timeoff)] wave = np.c_[time, current] prb.waveformType = "GENERAL" prb.currentwaveform(wave) prb.t0 = time.min() elif waveformType =="STEPOFF": prb.timeSteps = [(1e-5, 10), (5e-5, 10), (1e-4, 10), (5e-4, 10), (1e-3, 10),(5e-3, 10)] offset = 20. tobs = np.logspace(-4, -2, 21) rx = EM.TDEM.RxTDEM(np.array([[offset, 0., 0.]]), tobs, "bz") src = EM.TDEM.SrcTDEM_VMD_MVP([rx], np.array([[0., 0., 0.]]), waveformType=waveformType) survey = EM.TDEM.SurveyTDEM([src]) prb.Solver = MumpsSolver sigma = np.ones(mesh.nC)*1e-8 active = mesh.gridCC[:,2]<0. sig_half = 1e-2 sigma[active] = sig_half prb.pair(survey) out = survey.dpred(sigma) bz_ana = mu_0*hzAnalyticDipoleT(offset, rx.times, sig_half) err = np.linalg.norm(bz_ana-out)/np.linalg.norm(bz_ana) print '>> Relative error = ', err if showIt: plt.loglog(rx.times, bz_ana, 'k') plt.loglog(rx.times, out, 'b.') plt.show() return err
def test_asArray_N_x_Dim(self): true = np.array([[1, 2, 3]]) listArray = asArray_N_x_Dim([1, 2, 3], 3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) listArray = asArray_N_x_Dim(np.r_[1, 2, 3], 3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) listArray = asArray_N_x_Dim(np.array([[1, 2, 3.]]), 3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) true = np.array([[1, 2], [4, 5]]) listArray = asArray_N_x_Dim([[1, 2], [4, 5]], 2) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape)
def __init__( self, rxList, freq, S_e, integrate=True ): #, ePrimary=None, bPrimary=None, hPrimary=None, jPrimary=None): self._S_e = np.array(S_e, dtype=complex) self.freq = float(freq) self.integrate = integrate BaseSrc.__init__(self, rxList)
def __init__( self, rxList, freq, S_m, integrate=True ): #ePrimary=Zero(), bPrimary=Zero(), hPrimary=Zero(), jPrimary=Zero()): self._S_m = np.array(S_m, dtype=complex) self.freq = float(freq) self.integrate = integrate BaseSrc.__init__(self, rxList)
def fget(self): if(self._edge is None or self._tangents is None): if(self.dim == 2): xy = self.gridN A, D = Utils.indexCube('AD', self.vnC+1, np.array([self.nCx, self.nNy])) edge1 = xy[D, :] - xy[A, :] A, B = Utils.indexCube('AB', self.vnC+1, np.array([self.nNx, self.nCy])) edge2 = xy[B, :] - xy[A, :] self._edge = np.r_[Utils.mkvc(length2D(edge1)), Utils.mkvc(length2D(edge2))] self._tangents = np.r_[edge1, edge2]/np.c_[self._edge, self._edge] elif(self.dim == 3): xyz = self.gridN A, D = Utils.indexCube('AD', self.vnC+1, np.array([self.nCx, self.nNy, self.nNz])) edge1 = xyz[D, :] - xyz[A, :] A, B = Utils.indexCube('AB', self.vnC+1, np.array([self.nNx, self.nCy, self.nNz])) edge2 = xyz[B, :] - xyz[A, :] A, E = Utils.indexCube('AE', self.vnC+1, np.array([self.nNx, self.nNy, self.nCz])) edge3 = xyz[E, :] - xyz[A, :] self._edge = np.r_[Utils.mkvc(length3D(edge1)), Utils.mkvc(length3D(edge2)), Utils.mkvc(length3D(edge3))] self._tangents = np.r_[edge1, edge2, edge3]/np.c_[self._edge, self._edge, self._edge] return self._edge
def test_asArray_N_x_Dim(self): true = np.array([[1,2,3]]) listArray = asArray_N_x_Dim([1,2,3],3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) listArray = asArray_N_x_Dim(np.r_[1,2,3],3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) listArray = asArray_N_x_Dim(np.array([[1,2,3.]]),3) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape) true = np.array([[1,2],[4,5]]) listArray = asArray_N_x_Dim([[1,2],[4,5]],2) self.assertTrue(np.all(true == listArray)) self.assertTrue(true.shape == listArray.shape)
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 getInterpolationMat(self, loc, locType, zerosOutside=False): """ Produces interpolation matrix :param numpy.ndarray loc: Location of points to interpolate to :param str locType: What to interpolate (see below) :rtype: scipy.sparse.csr.csr_matrix :return: M, the interpolation matrix locType can be:: 'Ex' -> x-component of field defined on edges 'Ey' -> y-component of field defined on edges 'Ez' -> z-component of field defined on edges 'Fx' -> x-component of field defined on faces 'Fy' -> y-component of field defined on faces 'Fz' -> z-component of field defined on faces 'N' -> scalar field defined on nodes 'CC' -> scalar field defined on cell centers """ if self._meshType == 'CYL' and self.isSymmetric and locType in ['Ex','Ez','Fy']: raise Exception('Symmetric CylMesh does not support %s interpolation, as this variable does not exist.' % locType) loc = Utils.asArray_N_x_Dim(loc, self.dim) if zerosOutside is False: assert np.all(self.isInside(loc)), "Points outside of mesh" else: indZeros = np.logical_not(self.isInside(loc)) loc[indZeros, :] = np.array([v.mean() for v in self.getTensor('CC')]) if locType in ['Fx','Fy','Fz','Ex','Ey','Ez']: ind = {'x':0, 'y':1, 'z':2}[locType[1]] assert self.dim >= ind, 'mesh is not high enough dimension.' nF_nE = self.vnF if 'F' in locType else self.vnE components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE] components[ind] = Utils.interpmat(loc, *self.getTensor(locType)) # remove any zero blocks (hstack complains) components = [comp for comp in components if comp.shape[1] > 0] Q = sp.hstack(components) elif locType in ['CC', 'N']: Q = Utils.interpmat(loc, *self.getTensor(locType)) else: raise NotImplementedError('getInterpolationMat: locType=='+locType+' and mesh.dim=='+str(self.dim)) if zerosOutside: Q[indZeros, :] = 0 return Q.tocsr()
def unpackdx(fid,nrows): for ii in range(nrows): line = fid.readline() var = np.array(line.split(),dtype=float) if ii==0: x0= var[0] xvec = np.ones(int(var[2])) * (var[1] - var[0]) / int(var[2]) xend = var[1] else: xvec = np.hstack((xvec,np.ones(int(var[1])) * (var[0] - xend) / int(var[1]))) xend = var[0] return x0, xvec
def __init__(self, nodes): assert type(nodes) == list, "'nodes' variable must be a list of np.ndarray" assert len(nodes) > 1, "len(node) must be greater than 1" for i, nodes_i in enumerate(nodes): assert isinstance(nodes_i, np.ndarray), ("nodes[%i] is not a numpy array." % i) assert nodes_i.shape == nodes[0].shape, ("nodes[%i] is not the same shape as nodes[0]" % i) assert len(nodes[0].shape) == len(nodes), "Dimension mismatch" assert len(nodes[0].shape) > 1, "Not worth using Curv for a 1D mesh." BaseRectangularMesh.__init__(self, np.array(nodes[0].shape)-1, None) # Save nodes to private variable _gridN as vectors self._gridN = np.ones((nodes[0].size, self.dim)) for i, node_i in enumerate(nodes): self._gridN[:, i] = Utils.mkvc(node_i.astype(float))
def Jvec(self, m, v, u=None): """ Sensitivity times a vector. :param numpy.array m: inversion model (nP,) :param numpy.array v: vector which we take sensitivity 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 Jv = self.dataPair(self.survey) for freq in self.survey.freqs: A = self.getA(freq) # Ainv = self.Solver(A, **self.solverOpts) for src in self.survey.getSrcByFreq(freq): ftype = self._fieldType + 'Solution' u_src = u[src, ftype] dA_dm = self.getADeriv_m(freq, u_src, v) dRHS_dm = self.getRHSDeriv_m(freq, src, v) du_dm = Ainv * ( - dA_dm + dRHS_dm ) for rx in src.rxList: df_duFun = getattr(u, '_%sDeriv_u'%rx.projField, None) df_dudu_dm = df_duFun(src, du_dm, adjoint=False) df_dmFun = getattr(u, '_%sDeriv_m'%rx.projField, None) df_dm = df_dmFun(src, v, adjoint=False) Df_Dm = np.array(df_dudu_dm + df_dm,dtype=complex) P = lambda v: rx.projectFieldsDeriv(src, self.mesh, u, v) # wrt u, also have wrt m Jv[src, rx] = P(Df_Dm) Ainv.clean() return Utils.mkvc(Jv)
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, rxList, freq, s_m, s_e, **kwargs): self._s_m = np.array(s_m, dtype=complex) self._s_e = np.array(s_e, dtype=complex) self.freq = float(freq) BaseSrc.__init__(self, rxList, **kwargs)
def evalDeriv(self, src, mesh, f, v, adjoint=False): """ The derivative of the projection wrt u :param MTsrc src: MT source :param TensorMesh mesh: Mesh defining the topology of the problem :param MTfields f: MT fields object of the source :param numpy.ndarray v: Random vector of size """ real_or_imag = self.projComp if not adjoint: if self.projType is 'Z1D': Pex = mesh.getInterpolationMat(self.locs[:,-1],'Fx') Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex') # ex = Pex*mkvc(f[src,'e_1d'],2) # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0 dP_de = -mkvc(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Pex*v),2) dP_db = mkvc( Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))*(Pbx*f._bDeriv_u(src,v)/mu_0),2) PDeriv_complex = np.sum(np.hstack((dP_de,dP_db)),1) elif self.projType is 'Z2D': raise NotImplementedError('Has not been implement for 2D impedance tensor') elif self.projType is 'Z3D': if self.locs.ndim == 3: eFLocs = self.locs[:,:,0] bFLocs = self.locs[:,:,1] else: eFLocs = self.locs bFLocs = self.locs # Get the projection Pex = mesh.getInterpolationMat(eFLocs,'Ex') Pey = mesh.getInterpolationMat(eFLocs,'Ey') Pbx = mesh.getInterpolationMat(bFLocs,'Fx') Pby = mesh.getInterpolationMat(bFLocs,'Fy') # Get the fields at location # px: x-polaration and py: y-polaration. ex_px = Pex*f[src,'e_px'] ey_px = Pey*f[src,'e_px'] ex_py = Pex*f[src,'e_py'] ey_py = Pey*f[src,'e_py'] hx_px = Pbx*f[src,'b_px']/mu_0 hy_px = Pby*f[src,'b_px']/mu_0 hx_py = Pbx*f[src,'b_py']/mu_0 hy_py = Pby*f[src,'b_py']/mu_0 # Derivatives as lambda functions # The size of the diratives should be nD,nU ex_px_u = lambda vec: Pex*f._e_pxDeriv_u(src,vec) ey_px_u = lambda vec: Pey*f._e_pxDeriv_u(src,vec) ex_py_u = lambda vec: Pex*f._e_pyDeriv_u(src,vec) ey_py_u = lambda vec: Pey*f._e_pyDeriv_u(src,vec) # NOTE: Think b_p?Deriv_u should return a 2*nF size matrix hx_px_u = lambda vec: Pbx*f._b_pxDeriv_u(src,vec)/mu_0 hy_px_u = lambda vec: Pby*f._b_pxDeriv_u(src,vec)/mu_0 hx_py_u = lambda vec: Pbx*f._b_pyDeriv_u(src,vec)/mu_0 hy_py_u = lambda vec: Pby*f._b_pyDeriv_u(src,vec)/mu_0 # Update the input vector sDiag = lambda t: Utils.sdiag(mkvc(t,2)) # Define the components of the derivative Hd = sDiag(1./(sDiag(hx_px)*hy_py - sDiag(hx_py)*hy_px)) Hd_uV = sDiag(hy_py)*hx_px_u(v) + sDiag(hx_px)*hy_py_u(v) - sDiag(hx_py)*hy_px_u(v) - sDiag(hy_px)*hx_py_u(v) # Calculate components if 'zxx' in self.rxType: Zij = sDiag(Hd*( sDiag(ex_px)*hy_py - sDiag(ex_py)*hy_px )) ZijN_uV = sDiag(hy_py)*ex_px_u(v) + sDiag(ex_px)*hy_py_u(v) - sDiag(ex_py)*hy_px_u(v) - sDiag(hy_px)*ex_py_u(v) elif 'zxy' in self.rxType: Zij = sDiag(Hd*(-sDiag(ex_px)*hx_py + sDiag(ex_py)*hx_px )) ZijN_uV = -sDiag(hx_py)*ex_px_u(v) - sDiag(ex_px)*hx_py_u(v) + sDiag(ex_py)*hx_px_u(v) + sDiag(hx_px)*ex_py_u(v) elif 'zyx' in self.rxType: Zij = sDiag(Hd*( sDiag(ey_px)*hy_py - sDiag(ey_py)*hy_px )) ZijN_uV = sDiag(hy_py)*ey_px_u(v) + sDiag(ey_px)*hy_py_u(v) - sDiag(ey_py)*hy_px_u(v) - sDiag(hy_px)*ey_py_u(v) elif 'zyy' in self.rxType: Zij = sDiag(Hd*(-sDiag(ey_px)*hx_py + sDiag(ey_py)*hx_px )) ZijN_uV = -sDiag(hx_py)*ey_px_u(v) - sDiag(ey_px)*hx_py_u(v) + sDiag(ey_py)*hx_px_u(v) + sDiag(hx_px)*ey_py_u(v) # Calculate the complex derivative PDeriv_complex = Hd * (ZijN_uV - Zij * Hd_uV ) elif self.projType is 'T3D': if self.locs.ndim == 3: eFLocs = self.locs[:,:,0] bFLocs = self.locs[:,:,1] else: eFLocs = self.locs bFLocs = self.locs # Get the projection Pbx = mesh.getInterpolationMat(bFLocs,'Fx') Pby = mesh.getInterpolationMat(bFLocs,'Fy') Pbz = mesh.getInterpolationMat(bFLocs,'Fz') # Get the fields at location # px: x-polaration and py: y-polaration. bx_px = Pbx*f[src,'b_px'] by_px = Pby*f[src,'b_px'] bz_px = Pbz*f[src,'b_px'] bx_py = Pbx*f[src,'b_py'] by_py = Pby*f[src,'b_py'] bz_py = Pbz*f[src,'b_py'] # Derivatives as lambda functions # NOTE: Think b_p?Deriv_u should return a 2*nF size matrix bx_px_u = lambda vec: Pbx*f._b_pxDeriv_u(src,vec) by_px_u = lambda vec: Pby*f._b_pxDeriv_u(src,vec) bz_px_u = lambda vec: Pbz*f._b_pxDeriv_u(src,vec) bx_py_u = lambda vec: Pbx*f._b_pyDeriv_u(src,vec) by_py_u = lambda vec: Pby*f._b_pyDeriv_u(src,vec) bz_py_u = lambda vec: Pbz*f._b_pyDeriv_u(src,vec) # Update the input vector sDiag = lambda t: Utils.sdiag(mkvc(t,2)) # Define the components of the derivative Hd = sDiag(1./(sDiag(bx_px)*by_py - sDiag(bx_py)*by_px)) Hd_uV = sDiag(by_py)*bx_px_u(v) + sDiag(bx_px)*by_py_u(v) - sDiag(bx_py)*by_px_u(v) - sDiag(by_px)*bx_py_u(v) if 'tzx' in self.rxType: Tij = sDiag(Hd*( - sDiag(by_px)*bz_py + sDiag(by_py)*bz_px )) TijN_uV = -sDiag(by_px)*bz_py_u(v) - sDiag(bz_py)*by_px_u(v) + sDiag(by_py)*bz_px_u(v) + sDiag(bz_px)*by_py_u(v) elif 'tzy' in self.rxType: Tij = sDiag(Hd*( sDiag(bx_px)*bz_py - sDiag(bx_py)*bz_px )) TijN_uV = sDiag(bz_py)*bx_px_u(v) + sDiag(bx_px)*bz_py_u(v) - sDiag(bx_py)*bz_px_u(v) - sDiag(bz_px)*bx_py_u(v) # Calculate the complex derivative PDeriv_complex = Hd * (TijN_uV - Tij * Hd_uV ) # Extract the real number for the real/imag components. Pv = np.array(getattr(PDeriv_complex, real_or_imag)) elif adjoint: # Note: The v vector is real and the return should be complex if self.projType is 'Z1D': Pex = mesh.getInterpolationMat(self.locs[:,-1],'Fx') Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex') # ex = Pex*mkvc(f[src,'e_1d'],2) # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0 dP_deTv = -mkvc(Pex.T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*v,2) db_duv = Pbx.T/mu_0*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))).T*Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2)).T*v dP_dbTv = mkvc(f._bDeriv_u(src,db_duv,adjoint=True),2) PDeriv_real = np.sum(np.hstack((dP_deTv,dP_dbTv)),1) elif self.projType is 'Z2D': raise NotImplementedError('Has not be implement for 2D impedance tensor') elif self.projType is 'Z3D': if self.locs.ndim == 3: eFLocs = self.locs[:,:,0] bFLocs = self.locs[:,:,1] else: eFLocs = self.locs bFLocs = self.locs # Get the projection Pex = mesh.getInterpolationMat(eFLocs,'Ex') Pey = mesh.getInterpolationMat(eFLocs,'Ey') Pbx = mesh.getInterpolationMat(bFLocs,'Fx') Pby = mesh.getInterpolationMat(bFLocs,'Fy') # Get the fields at location # px: x-polaration and py: y-polaration. aex_px = mkvc(mkvc(f[src,'e_px'],2).T*Pex.T) aey_px = mkvc(mkvc(f[src,'e_px'],2).T*Pey.T) aex_py = mkvc(mkvc(f[src,'e_py'],2).T*Pex.T) aey_py = mkvc(mkvc(f[src,'e_py'],2).T*Pey.T) ahx_px = mkvc(mkvc(f[src,'b_px'],2).T/mu_0*Pbx.T) ahy_px = mkvc(mkvc(f[src,'b_px'],2).T/mu_0*Pby.T) ahx_py = mkvc(mkvc(f[src,'b_py'],2).T/mu_0*Pbx.T) ahy_py = mkvc(mkvc(f[src,'b_py'],2).T/mu_0*Pby.T) # Derivatives as lambda functions aex_px_u = lambda vec: f._e_pxDeriv_u(src,Pex.T*vec,adjoint=True) aey_px_u = lambda vec: f._e_pxDeriv_u(src,Pey.T*vec,adjoint=True) aex_py_u = lambda vec: f._e_pyDeriv_u(src,Pex.T*vec,adjoint=True) aey_py_u = lambda vec: f._e_pyDeriv_u(src,Pey.T*vec,adjoint=True) ahx_px_u = lambda vec: f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0 ahy_px_u = lambda vec: f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0 ahx_py_u = lambda vec: f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0 ahy_py_u = lambda vec: f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0 # Update the input vector # Define shortcuts sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2)) # Define the components of the derivative aHd = sDiag(1./(sDiag(ahx_px)*ahy_py - sDiag(ahx_py)*ahy_px)) aHd_uV = lambda x: ahx_px_u(sDiag(ahy_py)*x) + ahx_px_u(sDiag(ahy_py)*x) - ahy_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(ahy_px)*x) # Need to fix this to reflect the adjoint if 'zxx' in self.rxType: Zij = sDiag(aHd*( sDiag(ahy_py)*aex_px - sDiag(ahy_px)*aex_py)) ZijN_uV = lambda x: aex_px_u(sDiag(ahy_py)*x) + ahy_py_u(sDiag(aex_px)*x) - ahy_px_u(sDiag(aex_py)*x) - aex_py_u(sDiag(ahy_px)*x) elif 'zxy' in self.rxType: Zij = sDiag(aHd*(-sDiag(ahx_py)*aex_px + sDiag(ahx_px)*aex_py)) ZijN_uV = lambda x:-aex_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(aex_px)*x) + ahx_px_u(sDiag(aex_py)*x) + aex_py_u(sDiag(ahx_px)*x) elif 'zyx' in self.rxType: Zij = sDiag(aHd*( sDiag(ahy_py)*aey_px - sDiag(ahy_px)*aey_py)) ZijN_uV = lambda x: aey_px_u(sDiag(ahy_py)*x) + ahy_py_u(sDiag(aey_px)*x) - ahy_px_u(sDiag(aey_py)*x) - aey_py_u(sDiag(ahy_px)*x) elif 'zyy' in self.rxType: Zij = sDiag(aHd*(-sDiag(ahx_py)*aey_px + sDiag(ahx_px)*aey_py)) ZijN_uV = lambda x:-aey_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(aey_px)*x) + ahx_px_u(sDiag(aey_py)*x) + aey_py_u(sDiag(ahx_px)*x) # Calculate the complex derivative PDeriv_real = ZijN_uV(aHd*v) - aHd_uV(Zij.T*aHd*v)# # NOTE: Need to reshape the output to go from 2*nU array to a (nU,2) matrix for each polarization # PDeriv_real = np.hstack((mkvc(PDeriv_real[:len(PDeriv_real)/2],2),mkvc(PDeriv_real[len(PDeriv_real)/2::],2))) PDeriv_real = PDeriv_real.reshape((2,mesh.nE)).T elif self.projType is 'T3D': if self.locs.ndim == 3: bFLocs = self.locs[:,:,1] else: bFLocs = self.locs # Get the projection Pbx = mesh.getInterpolationMat(bFLocs,'Fx') Pby = mesh.getInterpolationMat(bFLocs,'Fy') Pbz = mesh.getInterpolationMat(bFLocs,'Fz') # Get the fields at location # px: x-polaration and py: y-polaration. abx_px = mkvc(mkvc(f[src,'b_px'],2).T*Pbx.T) aby_px = mkvc(mkvc(f[src,'b_px'],2).T*Pby.T) abz_px = mkvc(mkvc(f[src,'b_px'],2).T*Pbz.T) abx_py = mkvc(mkvc(f[src,'b_py'],2).T*Pbx.T) aby_py = mkvc(mkvc(f[src,'b_py'],2).T*Pby.T) abz_py = mkvc(mkvc(f[src,'b_py'],2).T*Pbz.T) # Derivatives as lambda functions abx_px_u = lambda vec: f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True) aby_px_u = lambda vec: f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True) abz_px_u = lambda vec: f._b_pxDeriv_u(src,Pbz.T*vec,adjoint=True) abx_py_u = lambda vec: f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True) aby_py_u = lambda vec: f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True) abz_py_u = lambda vec: f._b_pyDeriv_u(src,Pbz.T*vec,adjoint=True) # Update the input vector # Define shortcuts sDiag = lambda t: Utils.sdiag(mkvc(t,2)) sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2)) # Define the components of the derivative aHd = sDiag(1./(sDiag(abx_px)*aby_py - sDiag(abx_py)*aby_px)) aHd_uV = lambda x: abx_px_u(sDiag(aby_py)*x) + abx_px_u(sDiag(aby_py)*x) - aby_px_u(sDiag(abx_py)*x) - abx_py_u(sDiag(aby_px)*x) # Need to fix this to reflect the adjoint if 'tzx' in self.rxType: Tij = sDiag(aHd*( -sDiag(abz_py)*aby_px + sDiag(abz_px)*aby_py)) TijN_uV = lambda x: -abz_py_u(sDiag(aby_px)*x) - aby_px_u(sDiag(abz_py)*x) + aby_py_u(sDiag(abz_px)*x) + abz_px_u(sDiag(aby_py)*x) elif 'tzy' in self.rxType: Tij = sDiag(aHd*( sDiag(abz_py)*abx_px - sDiag(abz_px)*abx_py)) TijN_uV = lambda x: abx_px_u(sDiag(abz_py)*x) + abz_py_u(sDiag(abx_px)*x) - abx_py_u(sDiag(abz_px)*x) - abz_px_u(sDiag(abx_py)*x) # Calculate the complex derivative PDeriv_real = TijN_uV(aHd*v) - aHd_uV(Tij.T*aHd*v)# # NOTE: Need to reshape the output to go from 2*nU array to a (nU,2) matrix for each polarization # PDeriv_real = np.hstack((mkvc(PDeriv_real[:len(PDeriv_real)/2],2),mkvc(PDeriv_real[len(PDeriv_real)/2::],2))) PDeriv_real = PDeriv_real.reshape((2,mesh.nE)).T # Extract the data if real_or_imag == 'imag': Pv = 1j*PDeriv_real elif real_or_imag == 'real': Pv = PDeriv_real.astype(complex) return Pv
def MagneticDipoleVectorPotential(srcLoc, obsLoc, component, moment=1., orientation=np.r_[0., 0., 1.], mu=mu_0): """ Calculate the vector potential of a set of magnetic dipoles at given locations 'ref. <http://en.wikipedia.org/wiki/Dipole#Magnetic_vector_potential>' :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z) :param numpy.ndarray,SimPEG.Mesh obsLoc: Where the potentials will be calculated (x, y, z) or a SimPEG Mesh :param str,list component: The component to calculate - 'x', 'y', or 'z' if an array, or grid type if mesh, can be a list :param numpy.ndarray orientation: The vector dipole moment :rtype: numpy.ndarray :return: The vector potential each dipole at each observation location """ # TODO: break this out! if isinstance(orientation, str): orientation = orientationDict[orientation] assert np.linalg.norm(np.array(orientation), 2) == 1., ("orientation must " "be a unit vector") if type(component) in [list, tuple]: out = range(len(component)) for i, comp in enumerate(component): out[i] = MagneticDipoleVectorPotential(srcLoc, obsLoc, comp, orientation=orientation, mu=mu) return np.concatenate(out) if isinstance(obsLoc, Mesh.BaseMesh): mesh = obsLoc assert component in ['Ex', 'Ey', 'Ez', 'Fx', 'Fy', 'Fz'], ("Components" "must be in: ['Ex','Ey','Ez','Fx','Fy','Fz']") return MagneticDipoleVectorPotential(srcLoc, getattr(mesh, 'grid' + component), component[1], orientation=orientation) if component == 'x': dimInd = 0 elif component == 'y': dimInd = 1 elif component == 'z': dimInd = 2 else: raise ValueError('Invalid component') srcLoc = np.atleast_2d(srcLoc) obsLoc = np.atleast_2d(obsLoc) orientation = np.atleast_2d(orientation) nObs = obsLoc.shape[0] nSrc = srcLoc.shape[0] m = moment*np.array(orientation).repeat(nObs, axis=0) A = np.empty((nObs, nSrc)) for i in range(nSrc): dR = obsLoc - srcLoc[i, np.newaxis].repeat(nObs, axis=0) mCr = np.cross(m, dR) r = np.sqrt((dR**2).sum(axis=1)) A[:, i] = +(mu/(4*np.pi)) * mCr[:, dimInd]/(r**3) if nSrc == 1: return A.flatten() return A
def setUp(self): self.a = np.array([1, 2, 3]) self.b = np.array([1, 2]) self.c = np.array([1, 2, 3, 4])
def readDriverFile(self, input_file): """ Read input files for forward modeling MAG data with integral form INPUT: input_file: File name containing the forward parameter OUTPUT: mshfile obsfile topofile start model ref model mag model weightfile chi_target as, ax ,ay, az upper, lower bounds lp, lqx, lqy, lqz # All files should be in the working directory, # otherwise the path must be specified. """ fid = open(self.basePath + input_file, 'r') # Line 1: Mesh line = fid.readline() l_input = re.split('[!\s]', line) mshfile = l_input[1].rstrip() # Line 2: Observation file line = fid.readline() l_input = re.split('[!\s]', line) obsfile = l_input[1].rstrip() # Line 3: Topo, active-dyn, active-static topofile = None staticInput = None line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'TOPO': topofile = l_input[1].rstrip() elif l_input[0] == 'VALUE': staticInput = float(l_input[1]) elif l_input[0] == 'FILE': staticInput = l_input[1].rstrip() # Line 4: Starting model line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': mstart = float(l_input[1]) elif l_input[0] == 'FILE': mstart = l_input[1].rstrip() # Line 5: Reference model line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': mref = float(l_input[1]) elif l_input[0] == 'FILE': mref = l_input[1].rstrip() # Line 6: Magnetization model line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'DEFAULT': magfile = None elif l_input[0] == 'FILE': magfile = l_input[1].rstrip() # Line 7: Cell weights line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'DEFAULT': wgtfile = [] elif l_input[0] == 'FILE': wgtfile = l_input[1].rstrip() # Line 8: Target chi-factor line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'DEFAULT': chi = 1. elif l_input[0] == 'VALUE': chi = float(l_input[1]) # Line 9: Alpha values line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': val = np.array(l_input[1:5]) alphas = val.astype(np.float) elif l_input[0] == 'DEFAULT': alphas = np.ones(4) # Line 10: Bounds line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': val = np.array(l_input[1:3]) bounds = val.astype(np.float) elif l_input[0] == 'FILE': bounds = l_input[1].rstrip() else: bounds = [-np.inf, np.inf] # Line 11: Norms line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': val = np.array(l_input[1:6]) lpnorms = val.astype(np.float) elif l_input[0] == 'FILE': lpnorms = l_input[1].rstrip() # Line 12: Treshold values line = fid.readline() l_input = re.split('[!\s]', line) if l_input[0] == 'VALUE': val = np.array(l_input[1:3]) eps = val.astype(np.float) elif l_input[0] == 'DEFAULT': eps = None self.mshfile = mshfile self.obsfile = obsfile self.topofile = topofile self.mstart = mstart self._mrefInput = mref self._staticInput = staticInput self.magfile = magfile self.wgtfile = wgtfile self.chi = chi self.alphas = alphas self.bounds = bounds self.lpnorms = lpnorms self.eps = eps
def test_indexCube_2D(self): nN = np.array([3, 3]) self.assertTrue(np.all(indexCube('A', nN) == np.array([0, 1, 3, 4]))) self.assertTrue(np.all(indexCube('B', nN) == np.array([3, 4, 6, 7]))) self.assertTrue(np.all(indexCube('C', nN) == np.array([4, 5, 7, 8]))) self.assertTrue(np.all(indexCube('D', nN) == np.array([1, 2, 4, 5])))
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 getInterpolationMat(self, loc, locType='CC', zerosOutside=False): """ Produces interpolation matrix :param numpy.ndarray loc: Location of points to interpolate to :param str locType: What to interpolate (see below) :rtype: scipy.sparse.csr.csr_matrix :return: M, the interpolation matrix locType can be:: 'Ex' -> x-component of field defined on edges 'Ey' -> y-component of field defined on edges 'Ez' -> z-component of field defined on edges 'Fx' -> x-component of field defined on faces 'Fy' -> y-component of field defined on faces 'Fz' -> z-component of field defined on faces 'N' -> scalar field defined on nodes 'CC' -> scalar field defined on cell centers 'CCVx' -> x-component of vector field defined on cell centers 'CCVy' -> y-component of vector field defined on cell centers 'CCVz' -> z-component of vector field defined on cell centers """ if self._meshType == 'CYL' and self.isSymmetric and locType in [ 'Ex', 'Ez', 'Fy' ]: raise Exception( 'Symmetric CylMesh does not support %s interpolation, as this variable does not exist.' % locType) loc = Utils.asArray_N_x_Dim(loc, self.dim) if zerosOutside is False: assert np.all(self.isInside(loc)), "Points outside of mesh" else: indZeros = np.logical_not(self.isInside(loc)) loc[indZeros, :] = np.array( [v.mean() for v in self.getTensor('CC')]) if locType in ['Fx', 'Fy', 'Fz', 'Ex', 'Ey', 'Ez']: ind = {'x': 0, 'y': 1, 'z': 2}[locType[1]] assert self.dim >= ind, 'mesh is not high enough dimension.' nF_nE = self.vnF if 'F' in locType else self.vnE components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE] components[ind] = Utils.interpmat(loc, *self.getTensor(locType)) # remove any zero blocks (hstack complains) components = [comp for comp in components if comp.shape[1] > 0] Q = sp.hstack(components) elif locType in ['CC', 'N']: Q = Utils.interpmat(loc, *self.getTensor(locType)) elif locType in ['CCVx', 'CCVy', 'CCVz']: Q = Utils.interpmat(loc, *self.getTensor('CC')) Z = Utils.spzeros(loc.shape[0], self.nC) if locType == 'CCVx': Q = sp.hstack([Q, Z, Z]) elif locType == 'CCVy': Q = sp.hstack([Z, Q, Z]) elif locType == 'CCVz': Q = sp.hstack([Z, Z, Q]) else: raise NotImplementedError('getInterpolationMat: locType==' + locType + ' and mesh.dim==' + str(self.dim)) if zerosOutside: Q[indZeros, :] = 0 return Q.tocsr()
def run(plotIt=True): """ FLOW: Richards: 1D: Celia1990 ============================= There are two different forms of Richards equation that differ on how they deal with the non-linearity in the time-stepping term. The most fundamental form, referred to as the 'mixed'-form of Richards Equation Celia1990_ .. math:: \\frac{\partial \\theta(\psi)}{\partial t} - \\nabla \cdot k(\psi) \\nabla \psi - \\frac{\partial k(\psi)}{\partial z} = 0 \quad \psi \in \Omega where \\\\(\\\\theta\\\\) is water content, and \\\\(\\\\psi\\\\) is pressure head. This formulation of Richards equation is called the 'mixed'-form because the equation is parameterized in \\\\(\\\\psi\\\\) but the time-stepping is in terms of \\\\(\\\\theta\\\\). As noted in Celia1990_ the 'head'-based form of Richards equation can be written in the continuous form as: .. math:: \\frac{\partial \\theta}{\partial \psi} \\frac{\partial \psi}{\partial t} - \\nabla \cdot k(\psi) \\nabla \psi - \\frac{\partial k(\psi)}{\partial z} = 0 \quad \psi \in \Omega However, it can be shown that this does not conserve mass in the discrete formulation. Here we reproduce the results from Celia1990_ demonstrating the head-based formulation and the mixed-formulation. .. _Celia1990: http://www.webpages.uidaho.edu/ch/papers/Celia.pdf """ M = Mesh.TensorMesh([np.ones(40)]) M.setCellGradBC('dirichlet') params = Richards.Empirical.HaverkampParams().celia1990 params['Ks'] = np.log(params['Ks']) E = Richards.Empirical.Haverkamp(M, **params) bc = np.array([-61.5, -20.7]) h = np.zeros(M.nC) + bc[0] # bc = np.array([-20.7, -61.5]) # h = np.zeros(M.nC) + bc[1] def getFields(timeStep, method): timeSteps = np.ones(360 / timeStep) * timeStep prob = Richards.RichardsProblem(M, modelMap=E, boundaryConditions=bc, initialConditions=h, doNewton=False, method=method) prob.timeSteps = timeSteps return prob.fields(params['Ks']) Hs_M010 = getFields(10., 'mixed') Hs_M030 = getFields(30., 'mixed') Hs_M120 = getFields(120., 'mixed') Hs_H010 = getFields(10., 'head') Hs_H030 = getFields(30., 'head') Hs_H120 = getFields(120., 'head') if not plotIt: return plt.figure(figsize=(13, 5)) plt.subplot(121) plt.plot(40 - M.gridCC, Hs_M010[-1], 'b-') plt.plot(40 - M.gridCC, Hs_M030[-1], 'r-') plt.plot(40 - M.gridCC, Hs_M120[-1], 'k-') plt.ylim([-70, -10]) plt.title('Mixed Method') plt.xlabel('Depth, cm') plt.ylabel('Pressure Head, cm') plt.legend( ('$\Delta t$ = 10 sec', '$\Delta t$ = 30 sec', '$\Delta t$ = 120 sec')) plt.subplot(122) plt.plot(40 - M.gridCC, Hs_H010[-1], 'b-') plt.plot(40 - M.gridCC, Hs_H030[-1], 'r-') plt.plot(40 - M.gridCC, Hs_H120[-1], 'k-') plt.ylim([-70, -10]) plt.title('Head-Based Method') plt.xlabel('Depth, cm') plt.ylabel('Pressure Head, cm') plt.legend( ('$\Delta t$ = 10 sec', '$\Delta t$ = 30 sec', '$\Delta t$ = 120 sec'))