Esempio n. 1
0
        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
Esempio n. 2
0
    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()
Esempio n. 3
0
        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
Esempio n. 4
0
    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)
Esempio n. 5
0
File: FDEM.py Progetto: KyuboNoh/HY
    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)
Esempio n. 6
0
    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))
Esempio n. 7
0
    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
Esempio n. 9
0
    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)
Esempio n. 10
0
    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))
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
    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)
Esempio n. 14
0
 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])))
Esempio n. 15
0
    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)
Esempio n. 16
0
    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
Esempio n. 17
0
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
Esempio n. 18
0
    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
Esempio n. 19
0
    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
Esempio n. 20
0
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
Esempio n. 21
0
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
Esempio n. 22
0
 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])))
Esempio n. 23
0
    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
Esempio n. 24
0
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
Esempio n. 25
0
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
Esempio n. 26
0
 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)
Esempio n. 27
0
    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)
Esempio n. 28
0
    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)
Esempio n. 29
0
    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]
Esempio n. 30
0
    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)
Esempio n. 31
0
 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)
Esempio n. 32
0
    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))
Esempio n. 33
0
    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]
Esempio n. 34
0
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
Esempio n. 35
0
    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)
Esempio n. 36
0
    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)
Esempio n. 37
0
    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)
Esempio n. 38
0
 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
Esempio n. 39
0
 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
Esempio n. 40
0
    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)
Esempio n. 41
0
    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
Esempio n. 42
0
    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
Esempio n. 43
0
    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()
Esempio n. 44
0
 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
Esempio n. 45
0
    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
Esempio n. 46
0
    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))
Esempio n. 47
0
    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))
Esempio n. 48
0
File: FDEM.py Progetto: KyuboNoh/HY
    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)
Esempio n. 50
0
 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)
Esempio n. 51
0
    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
Esempio n. 52
0
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
Esempio n. 53
0
 def setUp(self):
     self.a = np.array([1, 2, 3])
     self.b = np.array([1, 2])
     self.c = np.array([1, 2, 3, 4])
Esempio n. 54
0
    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
Esempio n. 55
0
 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])))
Esempio n. 56
0
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
Esempio n. 57
0
    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'))