Example #1
0
def CasingMagDipole2Deriv_z_z(z):
    obsloc = np.vstack([xobs, yobs, z]).T

    f = Casing._getCasingHertzMagDipoleDeriv_z(srcloc,obsloc,freq,sigma,a,b,mu)
    g = Utils.sdiag(Casing._getCasingHertzMagDipole2Deriv_z_z(srcloc,obsloc,freq,sigma,a,b,mu))

    return f, g
Example #2
0
    def test_ana_forward(self):

        # Compute 3-component mag data
        self.survey.pair(self.prob_xyz)
        d = self.prob_xyz.fields(self.model)

        ndata = self.locXyz.shape[0]
        dbx = d[0:ndata]
        dby = d[ndata:2*ndata]
        dbz = d[2*ndata:]

        # Compute tmi mag data
        self.survey.pair(self.prob_tmi)
        dtmi = self.prob_tmi.fields(self.model)

        # Compute analytical response from a magnetized sphere
        bxa, bya, bza = PF.MagAnalytics.MagSphereFreeSpace(self.locXyz[:, 0],
                                                           self.locXyz[:, 1],
                                                           self.locXyz[:, 2],
                                                           self.rad, 0, 0, 0,
                                                           self.chi, self.b0)

        # Projection matrix
        Ptmi = mkvc(self.b0)/np.sqrt(np.sum(self.b0**2.))

        btmi = mkvc(Ptmi.dot(np.vstack((bxa, bya, bza))))

        err_xyz = (np.linalg.norm(d-np.r_[bxa, bya, bza]) /
                   np.linalg.norm(np.r_[bxa, bya, bza]))

        err_tmi = np.linalg.norm(dtmi-btmi)/np.linalg.norm(btmi)
        self.assertTrue(err_xyz < 0.005 and err_tmi < 0.005)
Example #3
0
def CasingMagDipoleDeriv_r(x):
    obsloc = np.vstack([x, yobs, zobs]).T

    f = Casing._getCasingHertzMagDipole(srcloc,obsloc,freq,sigma,a,b,mu)
    g = Utils.sdiag(Casing._getCasingHertzMagDipoleDeriv_r(srcloc,obsloc,freq,sigma,a,b,mu))

    return  f, g
Example #4
0
    def test_ana_forward(self):

        # Compute 3-component mag data
        self.survey.pair(self.prob_xyz)
        d = self.prob_xyz.fields(self.model)

        ndata = self.locXyz.shape[0]
        dbx = d[0:ndata]
        dby = d[ndata:2 * ndata]
        dbz = d[2 * ndata:]

        # Compute tmi mag data
        self.survey.pair(self.prob_tmi)
        dtmi = self.prob_tmi.fields(self.model)

        # Compute analytical response from a magnetized sphere
        bxa, bya, bza = PF.MagAnalytics.MagSphereFreeSpace(
            self.locXyz[:, 0], self.locXyz[:, 1], self.locXyz[:, 2], self.rad,
            0, 0, 0, self.chi, self.b0)

        # Projection matrix
        Ptmi = mkvc(self.b0) / np.sqrt(np.sum(self.b0**2.))

        btmi = mkvc(Ptmi.dot(np.vstack((bxa, bya, bza))))

        err_xyz = (np.linalg.norm(d - np.r_[bxa, bya, bza]) /
                   np.linalg.norm(np.r_[bxa, bya, bza]))

        err_tmi = np.linalg.norm(dtmi - btmi) / np.linalg.norm(btmi)
        self.assertTrue(err_xyz < 0.005 and err_tmi < 0.005)
Example #5
0
 def _e_pxDeriv_u(self, src, v, adjoint = False):
     '''
     Takes the derivative of e_px wrt u
     '''
     if adjoint:
         # adjoint: returns a 2*nE long vector with zero's for py
         return np.vstack((v,np.zeros_like(v)))
     # Not adjoint: return only the px part of the vector
     return v[:len(v)/2]
Example #6
0
def CasingMagDipoleDeriv_z(z):
    obsloc = np.vstack([xobs, yobs, z]).T

    f = Casing._getCasingHertzMagDipole(srcloc, obsloc, freq, sigma, a, b, mu)
    g = Utils.sdiag(
        Casing._getCasingHertzMagDipoleDeriv_z(srcloc, obsloc, freq, sigma, a,
                                               b, mu))

    return f, g
Example #7
0
 def _e_pyDeriv_u(self, src, v, adjoint=False):
     """
     Takes the derivative of e_py wrt u
     """
     if adjoint:
         # adjoint: returns a 2*nE long vector with zero's for px
         return np.vstack((np.zeros_like(v), v))
     # Not adjoint: return only the px part of the vector
     return v[len(v) / 2 : :]
Example #8
0
 def _e_pyDeriv_u(self, src, v, adjoint = False):
     '''
     Takes the derivative of e_py wrt u
     '''
     if adjoint:
         # adjoint: returns a 2*nE long vector with zero's for px
         return np.vstack((np.zeros_like(v),v))
     # Not adjoint: return only the px part of the vector
     return v[len(v)/2::]
Example #9
0
def run(plotIt=True):
    """
        Mesh: Basic Forward 2D DC Resistivity
        =====================================

        2D DC forward modeling example with Tensor and Curvilinear Meshes
    """

    # Step1: Generate Tensor and Curvilinear Mesh
    sz = [40, 40]
    tM = Mesh.TensorMesh(sz)
    rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz, 'rotate'))

    # Step2: Direct Current (DC) operator
    def DCfun(mesh, pts):
        D = mesh.faceDiv
        sigma = 1e-2 * np.ones(mesh.nC)
        MsigI = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True)
        A = -D * MsigI * D.T
        A[-1, -1] /= mesh.vol[-1]  # Remove null space
        rhs = np.zeros(mesh.nC)
        txind = Utils.meshutils.closestPoints(mesh, pts)
        rhs[txind] = np.r_[1, -1]
        return A, rhs

    pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))

    #Step3: Solve DC problem (LU solver)
    AtM, rhstM = DCfun(tM, pts)
    AinvtM = SolverLU(AtM)
    phitM = AinvtM * rhstM

    ArM, rhsrM = DCfun(rM, pts)
    AinvrM = SolverLU(ArM)
    phirM = AinvrM * rhsrM

    if not plotIt: return

    import matplotlib.pyplot as plt

    #Step4: Making Figure
    fig, axes = plt.subplots(1, 2, figsize=(12 * 1.2, 4 * 1.2))
    vmin, vmax = phitM.min(), phitM.max()
    dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)
    dat = rM.plotImage(phirM, ax=axes[1], clim=(vmin, vmax), grid=True)
    cb = plt.colorbar(dat[0], ax=axes[0])
    cb.set_label("Voltage (V)")
    cb = plt.colorbar(dat[0], ax=axes[1])
    cb.set_label("Voltage (V)")

    axes[0].set_title('TensorMesh')
    axes[1].set_title('CurvilinearMesh')
    plt.show()
Example #10
0
def run(plotIt=True):

    """
        Mesh: Basic Forward 2D DC Resistivity
        =====================================

        2D DC forward modeling example with Tensor and Curvilinear Meshes
    """

    # Step1: Generate Tensor and Curvilinear Mesh
    sz = [40,40]
    tM = Mesh.TensorMesh(sz)
    rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))

    # Step2: Direct Current (DC) operator
    def DCfun(mesh, pts):
        D = mesh.faceDiv
        sigma = 1e-2*np.ones(mesh.nC)
        MsigI = mesh.getFaceInnerProduct(sigma, invProp=True, invMat=True)
        A = -D*MsigI*D.T
        A[-1,-1] /= mesh.vol[-1] # Remove null space
        rhs = np.zeros(mesh.nC)
        txind = Utils.meshutils.closestPoints(mesh, pts)
        rhs[txind] = np.r_[1,-1]
        return A, rhs

    pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))

    #Step3: Solve DC problem (LU solver)
    AtM, rhstM = DCfun(tM, pts)
    AinvtM = SolverLU(AtM)
    phitM = AinvtM*rhstM

    ArM, rhsrM = DCfun(rM, pts)
    AinvrM = SolverLU(ArM)
    phirM = AinvrM*rhsrM

    if not plotIt: return

    import matplotlib.pyplot as plt

    #Step4: Making Figure
    fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
    vmin, vmax = phitM.min(), phitM.max()
    dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)
    dat = rM.plotImage(phirM, ax=axes[1], clim=(vmin, vmax), grid=True)
    cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)")
    cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)")

    axes[0].set_title('TensorMesh')
    axes[1].set_title('CurvilinearMesh')
    plt.show()
Example #11
0
    def _fDeriv_u(self, src, v, adjoint=False):
        """
        Derivative of the fields object wrt u.

        :param MTsrc src: MT source
        :param numpy.ndarray v: random vector of f_sol.size
        This function stacks the fields derivatives appropriately

        return a vector of size (nreEle+nrbEle)
        """

        de_du = v  # Utils.spdiag(np.ones((self.nF,)))
        db_du = self._bDeriv_u(src, v, adjoint)
        # Return the stack
        # This doesn't work...
        return np.vstack((de_du, db_du))
Example #12
0
    def _fDeriv_u(self, src, v, adjoint=False):
        """
        Derivative of the fields object wrt u.

        :param MTsrc src: MT source
        :param numpy.ndarray v: random vector of f_sol.size
        This function stacks the fields derivatives appropriately

        return a vector of size (nreEle+nrbEle)
        """

        de_du = v #Utils.spdiag(np.ones((self.nF,)))
        db_du = self._bDeriv_u(src, v, adjoint)
        # Return the stack
        # This doesn't work...
        return np.vstack((de_du,db_du))
Example #13
0
def getActiveindfromTopo(mesh, topo):
# def genActiveindfromTopo(mesh, topo):
    """
        Get active indices from topography
    """
    from scipy.interpolate import NearestNDInterpolator
    if mesh.dim==3:
        nCxy = mesh.nCx*mesh.nCy
        Zcc = mesh.gridCC[:,2].reshape((nCxy, mesh.nCz), order='F')
        Ftopo = NearestNDInterpolator(topo[:,:2], topo[:,2])
        XY = Utils.ndgrid(mesh.vectorCCx, mesh.vectorCCy)
        XY.shape
        topo = Ftopo(XY)
        actind = []
        for ixy in range(nCxy):
            actind.append(topo[ixy] <= Zcc[ixy,:])
    else:
        raise NotImplementedError("Only 3D is working")

    return Utils.mkvc(np.vstack(actind))
Example #14
0
    def projectFields(self, u):
        """
            Decompose frequency domain EM responses as real and imaginary
            components
        """

        ureal = (u.real).copy()
        uimag = (u.imag).copy()

        if self.rxType == 'Hz':

            if self.switchRI == 'all':

                ureal = (u.real).copy()
                uimag = (u.imag).copy()
                if ureal.ndim == 1 or 0:
                    resp = np.r_[ureal, uimag]
                elif ureal.ndim ==2:
                    resp = np.vstack((ureal, uimag))
                else:
                    raise Exception('Not implemented!!')


            elif self.switchRI == 'Real':

                resp = (u.real).copy()

            elif self.switchRI == 'Imag':

                resp = (u.imag).copy()

            else:

                raise Exception('Not implemented')

        else:

            raise Exception('Not implemnted!!')

        return mu_0*resp
Example #15
0
    def magnetizationModel(self):
        """
            magnetization vector
        """

        if getattr(self, 'magfile', None) is None:

            M = Magnetics.dipazm_2_xyz(np.ones(self.nC) *
                                       self.survey.srcField.param[1],
                                       np.ones(self.nC) *
                                       self.survey.srcField.param[2])

        else:

            with open(self.basePath + self.magfile) as f:
                magmodel = f.read()

            magmodel = magmodel.splitlines()
            M = []

            for line in magmodel:
                M.append(map(float, line.split()))

            # Convert list to 2d array
            M = np.vstack(M)

            # Cycle through three components and permute from UBC to SimPEG
            for ii in range(3):
                m = np.reshape(M[:, ii],
                               (self.mesh.nCz, self.mesh.nCx, self.mesh.nCy),
                               order='F')

                m = m[::-1, :, :]
                m = np.transpose(m, (1, 2, 0))
                M[:, ii] = Utils.mkvc(m)

        self._M = M

        return self._M
Example #16
0
# Step2: Direct Current (DC) operator
def DCfun(mesh, pts):
    D = mesh.faceDiv
    G = D.T
    sigma = 1e-2 * np.ones(mesh.nC)
    Msigi = mesh.getFaceInnerProduct(1.0 / sigma)
    MsigI = Utils.sdInv(Msigi)
    A = D * MsigI * G
    A[-1, -1] /= mesh.vol[-1]  # Remove null space
    rhs = np.zeros(mesh.nC)
    txind = Utils.meshutils.closestPoints(mesh, pts)
    rhs[txind] = np.r_[1, -1]
    return A, rhs


pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))

# Step3: Solve DC problem (LU solver)
AtM, rhstM = DCfun(tM, pts)
AinvtM = SolverLU(AtM)
phitM = AinvtM * rhstM

ArM, rhsrM = DCfun(rM, pts)
AinvrM = SolverLU(ArM)
phirM = AinvrM * rhsrM

# Step4: Making Figure
fig, axes = plt.subplots(1, 2, figsize=(12 * 1.2, 4 * 1.2))
label = ["(a)", "(b)"]
opts = {}
vmin, vmax = phitM.min(), phitM.max()
Example #17
0
def readUBC_DC3Dobstopo(filename,mesh,topo,probType="CC"):
    """
     Seogi's personal readObs function.

    """
    text_file = open(filename, "r")
    lines = text_file.readlines()
    text_file.close()
    SRC = []
    DATA = []
    srcLists = []
    isrc = 0
    # airind = getActiveindfromTopo(mesh, topo)
    # mesh2D, topoCC = gettopoCC(mesh, airind)

    for line in lines:
        if "!" in line.split(): continue
        elif line == '\n': continue
        elif line == ' \n': continue
        temp =  map(float, line.split())
        # Read a line for the current electrode
        if len(temp) == 5: # SRC: Only X and Y are provided (assume no topography)
            #TODO consider topography and assign the closest cell center in the earth
            if isrc == 0:
                DATA_temp = []
            else:
                DATA.append(np.asarray(DATA_temp))
                DATA_temp = []
                indM = Utils.closestPoints(mesh2D, DATA[isrc-1][:,1:3])
                indN = Utils.closestPoints(mesh2D, DATA[isrc-1][:,3:5])
                rx = DCIP.RxDipole(np.c_[DATA[isrc-1][:,1:3], topoCC[indM]], np.c_[DATA[isrc-1][:,3:5], topoCC[indN]])
                temp = np.asarray(temp)
                if [SRC[isrc-1][0], SRC[isrc-1][1]] == [SRC[isrc-1][2], SRC[isrc-1][3]]:
                    indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]])
                    tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[mesh.vectorCCx.max(), mesh.vectorCCy.max(), topoCC[-1]])
                else:
                    indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]])
                    indB = Utils.closestPoints(mesh2D, [SRC[isrc-1][2], SRC[isrc-1][3]])
                    tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[SRC[isrc-1][2], SRC[isrc-1][3], topoCC[indB]])
                srcLists.append(tx)
            SRC.append(temp)
            isrc += 1
        elif len(temp) == 7: # SRC: X, Y and Z are provided
            SRC.append(temp)
            isrc += 1
        elif len(temp) == 6: #
            DATA_temp.append(np.r_[isrc, np.asarray(temp)])
        elif len(temp) > 7:
            DATA_temp.append(np.r_[isrc, np.asarray(temp)])

    DATA.append(np.asarray(DATA_temp))
    DATA_temp = []
    indM = Utils.closestPoints(mesh2D, DATA[isrc-1][:,1:3])
    indN = Utils.closestPoints(mesh2D, DATA[isrc-1][:,3:5])
    rx = DCIP.RxDipole(np.c_[DATA[isrc-1][:,1:3], topoCC[indM]], np.c_[DATA[isrc-1][:,3:5], topoCC[indN]])
    temp = np.asarray(temp)
    if [SRC[isrc-1][0], SRC[isrc-1][1]] == [SRC[isrc-1][2], SRC[isrc-1][3]]:
        indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]])
        tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[mesh.vectorCCx.max(), mesh.vectorCCy.max(), topoCC[-1]])
    else:
        indA = Utils.closestPoints(mesh2D, [SRC[isrc-1][0], SRC[isrc-1][1]])
        indB = Utils.closestPoints(mesh2D, [SRC[isrc-1][2], SRC[isrc-1][3]])
        tx = DCIP.SrcDipole([rx], [SRC[isrc-1][0], SRC[isrc-1][1], topoCC[indA]],[SRC[isrc-1][2], SRC[isrc-1][3], topoCC[indB]])
    srcLists.append(tx)
    text_file.close()
    survey = DCIP.SurveyDC(srcLists)

    # Do we need this?
    SRC = np.asarray(SRC)
    DATA = np.vstack(DATA)
    survey.dobs = np.vstack(DATA)[:,-2]


    return {'DCsurvey':survey, 'airind':airind, 'topoCC':topoCC, 'SRC':SRC}
Example #18
0
def interpFFT(x, y, m):
    """ 
    Load in a 2D grid and resample
    
    OUTPUT:
    m_out


     """

    from SimPEG import np, sp
    import scipy.signal as sn

    # Add padding values by reflection (2**n)
    lenx = np.round(np.log2(2 * len(x)))
    npadx = int(np.floor((2**lenx - len(x)) / 2.))

    #Create hemming taper
    if np.mod(npadx * 2 + len(x), 2) != 0:
        oddx = 1

    else:
        oddx = 0

    tap0 = sn.hamming(npadx * 2)
    tapl = sp.spdiags(tap0[0:npadx], 0, npadx, npadx)
    tapr = sp.spdiags(tap0[npadx:], 0, npadx, npadx + oddx)

    # Mirror the 2d data over the half lenght and apply 0-taper
    mpad = np.hstack(
        [np.fliplr(m[:, 0:npadx]) * tapl, m,
         np.fliplr(m[:, -npadx:]) * tapr])

    # Repeat along the second dimension
    leny = np.round(np.log2(2 * len(y)))
    npady = int(np.floor((2**leny - len(y)) / 2.))

    #Create hemming taper
    if np.mod(npady * 2 + len(y), 2) != 0:
        oddy = 1

    else:
        oddy = 0

    tap0 = sn.hamming(npady * 2)
    tapu = sp.spdiags(tap0[0:npady], 0, npady, npady)
    tapd = sp.spdiags(tap0[npady:], 0, npady + oddy, npady)

    mpad = np.vstack([
        tapu * np.flipud(mpad[0:npady, :]), mpad,
        tapd * np.flipud(mpad[-npady:, :])
    ])

    # Compute FFT
    FFTm = np.fft.fft2(mpad)

    # Do an FFT shift
    FFTshift = np.fft.fftshift(FFTm)

    # Pad high frequencies with zeros to increase the sampling rate
    py = int(FFTm.shape[0] / 2)
    px = int(FFTm.shape[1] / 2)

    FFTshift = np.hstack([
        np.zeros((FFTshift.shape[0], px)), FFTshift,
        np.zeros((FFTshift.shape[0], px))
    ])
    FFTshift = np.vstack([
        np.zeros((py, FFTshift.shape[1])), FFTshift,
        np.zeros((py, FFTshift.shape[1]))
    ])

    # Inverse shift
    FFTm = np.fft.ifftshift(FFTshift)

    # Compute inverse FFT
    IFFTm = np.fft.ifft2(FFTm) * FFTm.size / mpad.size

    m_out = np.real(IFFTm)
    # Extract core
    #m_out = np.real(IFFTm[npady*2:-(npady*2+oddy+1),npadx*2:-(npadx*2+oddx+1)])

    m_out = m_out[npady * 2:-(npady + oddy) * 2, npadx * 2:-(npadx + oddx) * 2]

    if np.mod(m.shape[0], 2) != 0:
        m_out = m_out[:-1, :]

    if np.mod(m.shape[1], 2) != 0:
        m_out = m_out[:, :-1]

    return m_out
Example #19
0
def run(plotIt=True):
    # Step1: Generate Tensor and Curvilinear Mesh
    sz = [40,40]
    # Tensor Mesh
    tM = Mesh.TensorMesh(sz)
    # Curvilinear Mesh
    rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz,'rotate'))
    # Step2: Direct Current (DC) operator
    def DCfun(mesh, pts):
        D = mesh.faceDiv
        G = D.T
        sigma = 1e-2*np.ones(mesh.nC)
        Msigi = mesh.getFaceInnerProduct(1./sigma)
        MsigI = Utils.sdInv(Msigi)
        A = D*MsigI*G
        A[-1,-1] /= mesh.vol[-1] # Remove null space
        rhs = np.zeros(mesh.nC)
        txind = Utils.meshutils.closestPoints(mesh, pts)
        rhs[txind] = np.r_[1,-1]
        return A, rhs

    pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))

    #Step3: Solve DC problem (LU solver)
    AtM, rhstM = DCfun(tM, pts)
    AinvtM = SolverLU(AtM)
    phitM = AinvtM*rhstM

    ArM, rhsrM = DCfun(rM, pts)
    AinvrM = SolverLU(ArM)
    phirM = AinvrM*rhsrM

    if not plotIt: return

    import matplotlib.pyplot as plt
    import matplotlib
    from matplotlib.mlab import griddata

    #Step4: Making Figure
    fig, axes = plt.subplots(1,2,figsize=(12*1.2,4*1.2))
    label = ["(a)", "(b)"]
    opts = {}
    vmin, vmax = phitM.min(), phitM.max()
    dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)

    #TODO: At the moment Curvilinear Mesh do not have plotimage

    Xi = tM.gridCC[:,0].reshape(sz[0], sz[1], order='F')
    Yi = tM.gridCC[:,1].reshape(sz[0], sz[1], order='F')
    PHIrM = griddata(rM.gridCC[:,0], rM.gridCC[:,1], phirM, Xi, Yi, interp='linear')
    axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax)

    cb = plt.colorbar(dat[0], ax=axes[0]); cb.set_label("Voltage (V)")
    cb = plt.colorbar(dat[0], ax=axes[1]); cb.set_label("Voltage (V)")

    tM.plotGrid(ax=axes[0], **opts)
    axes[0].set_title('TensorMesh')
    rM.plotGrid(ax=axes[1], **opts)
    axes[1].set_title('CurvilinearMesh')
    for i in range(2):
        axes[i].set_xlim(0.025, 0.975)
        axes[i].set_ylim(0.025, 0.975)
        axes[i].text(0., 1.0, label[i], fontsize=20)
        if i==0:
            axes[i].set_ylabel("y")
        else:
            axes[i].set_ylabel(" ")
        axes[i].set_xlabel("x")
    plt.show()
Example #20
0
def MagneticDipoleFields(srcLoc, obsLoc, component,
                         orientation='Z', moment=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>'

        .. math::

            B = \frac{\mu_0}{4 \pi r^3} \left( \frac{3 \vec{r} (\vec{m} \cdot
                                                                \vec{r})}{r^2})
                                                - \vec{m}
                                        \right) \cdot{\hat{rx}}

        :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z)
        :param numpy.ndarray obsLoc: Where the potentials will be calculated
                                     (x, y, z)
        :param str component: The component to calculate - 'x', 'y', or 'z'
        :param numpy.ndarray moment: The vector dipole moment (vertical)
        :rtype: numpy.ndarray
        :return: The vector potential each dipole at each observation location
    """

    if isinstance(orientation, str):
        assert orientation.upper() in ['X', 'Y', 'Z'], ("orientation must be 'x', "
                                                      "'y', or 'z' or a vector"
                                                      "not {}".format(orientation)
                                                      )
    elif (not np.allclose(np.r_[1., 0., 0.], orientation) or
          not np.allclose(np.r_[0., 1., 0.], orientation) or
          not np.allclose(np.r_[0., 0., 1.], orientation)):
        warnings.warn('Arbitrary trasnmitter orientations ({}) not thouroughly tested '
                      'Pull request on a test anyone? bueller?').format(orientation)

    if isinstance(component, str):
        assert component.upper() in ['X', 'Y', 'Z'], ("component must be 'x', "
                                                      "'y', or 'z' or a vector"
                                                      "not {}".format(component)
                                                      )
    elif (not np.allclose(np.r_[1., 0., 0.], component) or
          not np.allclose(np.r_[0., 1., 0.], component) or
          not np.allclose(np.r_[0., 0., 1.], component)):
        warnings.warn('Arbitrary receiver orientations ({}) not thouroughly tested '
                      'Pull request on a test anyone? bueller?').format(component)

    if isinstance(orientation, str):
        orientation = orientationDict[orientation.upper()]

    if isinstance(component, str):
        component = orientationDict[component.upper()]

    assert np.linalg.norm(orientation, 2) == 1., ('orientation must be a unit '
                                                  'vector. Use "moment=X to '
                                                  'scale source fields')

    if np.linalg.norm(component, 2) != 1.:
        warnings.warn('The magnitude of the receiver component vector is > 1, '
                      ' it is {}. The receiver fields will be scaled.'
                      ).format(np.linalg.norm(component, 2))

    srcLoc = np.atleast_2d(srcLoc)
    component = np.atleast_2d(component)
    obsLoc = np.atleast_2d(obsLoc)
    orientation = np.atleast_2d(orientation)

    nObs = obsLoc.shape[0]
    nSrc = int(srcLoc.size / 3.)

    # use outer product to construct an array of [x_src, y_src, z_src]

    m = moment*orientation.repeat(nObs, axis=0)
    B = []

    for i in range(nSrc):
        srcLoc = srcLoc[i, np.newaxis].repeat(nObs, axis=0)
        rx = component.repeat(nObs, axis=0)
        dR = obsLoc - srcLoc
        r = np.sqrt((dR**2).sum(axis=1))

        # mult each element and sum along the axis (vector dot product)
        m_dot_dR_div_r2 = (m * dR).sum(axis=1) / (r**2)

        # multiply the scalar m_dot_dR by the 3D vector r
        rvec_m_dot_dR_div_r2 = np.vstack([m_dot_dR_div_r2 * dR[:, i] for
                                          i in range(3)]).T
        inside = (3. * rvec_m_dot_dR_div_r2) - m

        # dot product with rx orientation
        inside_dot_rx = (inside * rx).sum(axis=1)
        front = (mu/(4.* np.pi * r**3))

        B.append(Utils.mkvc(front * inside_dot_rx))

    return np.vstack(B).T
Example #21
0
# Compute tmi mag data
survey.pair(prob_tmi)
dtmi = prob_tmi.fields(m)

# Compute analytical response from a magnetized sphere
bxa, bya, bza = PF.MagAnalytics.MagSphereFreeSpace(locXyz[:, 0],
                                                   locXyz[:, 1],
                                                   locXyz[:, 2],
                                                   rad, 0, 0, 0,
                                                   chi, b0)

# Projection matrix
Ptmi = mkvc(b0)/np.sqrt(np.sum(b0**2.))

btmi = mkvc(Ptmi.dot(np.vstack((bxa, bya, bza))))

err_xyz = (np.linalg.norm(d-np.r_[bxa, bya, bza]) /
           np.linalg.norm(np.r_[bxa, bya, bza]))

err_tmi = np.linalg.norm(dtmi-btmi)/np.linalg.norm(btmi)

#fig = plt.figure()
#axs = plt.subplot(111)
#mesh.plotSlice(model, normal='Z', ind = mesh.nCz/2, ax= axs)
#axs.set_aspect('equal')

#PF.Magnetics.plot_obs_2D(locXyz,dtmi)

#%% Repeat using PDE solve
m_mu = PF.BaseMag.BaseMagMap(mesh)
def run(plotIt=True):
    # Step1: Generate Tensor and Curvilinear Mesh
    sz = [40, 40]
    # Tensor Mesh
    tM = Mesh.TensorMesh(sz)
    # Curvilinear Mesh
    rM = Mesh.CurvilinearMesh(Utils.meshutils.exampleLrmGrid(sz, 'rotate'))

    # Step2: Direct Current (DC) operator
    def DCfun(mesh, pts):
        D = mesh.faceDiv
        G = D.T
        sigma = 1e-2 * np.ones(mesh.nC)
        Msigi = mesh.getFaceInnerProduct(1. / sigma)
        MsigI = Utils.sdInv(Msigi)
        A = D * MsigI * G
        A[-1, -1] /= mesh.vol[-1]  # Remove null space
        rhs = np.zeros(mesh.nC)
        txind = Utils.meshutils.closestPoints(mesh, pts)
        rhs[txind] = np.r_[1, -1]
        return A, rhs

    pts = np.vstack((np.r_[0.25, 0.5], np.r_[0.75, 0.5]))

    #Step3: Solve DC problem (LU solver)
    AtM, rhstM = DCfun(tM, pts)
    AinvtM = SolverLU(AtM)
    phitM = AinvtM * rhstM

    ArM, rhsrM = DCfun(rM, pts)
    AinvrM = SolverLU(ArM)
    phirM = AinvrM * rhsrM

    if not plotIt: return

    import matplotlib.pyplot as plt
    import matplotlib
    from matplotlib.mlab import griddata

    #Step4: Making Figure
    fig, axes = plt.subplots(1, 2, figsize=(12 * 1.2, 4 * 1.2))
    label = ["(a)", "(b)"]
    opts = {}
    vmin, vmax = phitM.min(), phitM.max()
    dat = tM.plotImage(phitM, ax=axes[0], clim=(vmin, vmax), grid=True)

    #TODO: At the moment Curvilinear Mesh do not have plotimage

    Xi = tM.gridCC[:, 0].reshape(sz[0], sz[1], order='F')
    Yi = tM.gridCC[:, 1].reshape(sz[0], sz[1], order='F')
    PHIrM = griddata(rM.gridCC[:, 0],
                     rM.gridCC[:, 1],
                     phirM,
                     Xi,
                     Yi,
                     interp='linear')
    axes[1].contourf(Xi, Yi, PHIrM, 100, vmin=vmin, vmax=vmax)

    cb = plt.colorbar(dat[0], ax=axes[0])
    cb.set_label("Voltage (V)")
    cb = plt.colorbar(dat[0], ax=axes[1])
    cb.set_label("Voltage (V)")

    tM.plotGrid(ax=axes[0], **opts)
    axes[0].set_title('TensorMesh')
    rM.plotGrid(ax=axes[1], **opts)
    axes[1].set_title('CurvilinearMesh')
    for i in range(2):
        axes[i].set_xlim(0.025, 0.975)
        axes[i].set_ylim(0.025, 0.975)
        axes[i].text(0., 1.0, label[i], fontsize=20)
        if i == 0:
            axes[i].set_ylabel("y")
        else:
            axes[i].set_ylabel(" ")
        axes[i].set_xlabel("x")
    plt.show()
Example #23
0
def MagneticDipoleFields(srcLoc, obsLoc, component,
                         orientation='Z', moment=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>'

        .. math::

            B = \frac{\mu_0}{4 \pi r^3} \left( \frac{3 \vec{r} (\vec{m} \cdot
                                                                \vec{r})}{r^2})
                                                - \vec{m}
                                        \right) \cdot{\hat{rx}}

        :param numpy.ndarray srcLoc: Location of the source(s) (x, y, z)
        :param numpy.ndarray obsLoc: Where the potentials will be calculated
                                     (x, y, z)
        :param str component: The component to calculate - 'x', 'y', or 'z'
        :param numpy.ndarray moment: The vector dipole moment (vertical)
        :rtype: numpy.ndarray
        :return: The vector potential each dipole at each observation location
    """

    if isinstance(orientation, str):
        assert orientation.upper() in ['X', 'Y', 'Z'], ("orientation must be 'x', "
                                                      "'y', or 'z' or a vector"
                                                      "not {}".format(orientation)
                                                      )
    elif (not np.allclose(np.r_[1., 0., 0.], orientation) or
          not np.allclose(np.r_[0., 1., 0.], orientation) or
          not np.allclose(np.r_[0., 0., 1.], orientation)):
        warnings.warn('Arbitrary trasnmitter orientations ({}) not thouroughly tested '
                      'Pull request on a test anyone? bueller?').format(orientation)

    if isinstance(component, str):
        assert component.upper() in ['X', 'Y', 'Z'], ("component must be 'x', "
                                                      "'y', or 'z' or a vector"
                                                      "not {}".format(component)
                                                      )
    elif (not np.allclose(np.r_[1., 0., 0.], component) or
          not np.allclose(np.r_[0., 1., 0.], component) or
          not np.allclose(np.r_[0., 0., 1.], component)):
        warnings.warn('Arbitrary receiver orientations ({}) not thouroughly tested '
                      'Pull request on a test anyone? bueller?').format(component)

    if isinstance(orientation, str):
        orientation = orientationDict[orientation.upper()]

    if isinstance(component, str):
        component = orientationDict[component.upper()]

    assert np.linalg.norm(orientation, 2) == 1., ('orientation must be a unit '
                                                  'vector. Use "moment=X to '
                                                  'scale source fields')

    if np.linalg.norm(component, 2) != 1.:
        warnings.warn('The magnitude of the receiver component vector is > 1, '
                      ' it is {}. The receiver fields will be scaled.'
                      ).format(np.linalg.norm(component, 2))

    srcLoc = np.atleast_2d(srcLoc)
    component = np.atleast_2d(component)
    obsLoc = np.atleast_2d(obsLoc)
    orientation = np.atleast_2d(orientation)

    nObs = obsLoc.shape[0]
    nSrc = int(srcLoc.size / 3.)

    # use outer product to construct an array of [x_src, y_src, z_src]

    m = moment*orientation.repeat(nObs, axis=0)
    B = []

    for i in range(nSrc):
        srcLoc = srcLoc[i, np.newaxis].repeat(nObs, axis=0)
        rx = component.repeat(nObs, axis=0)
        dR = obsLoc - srcLoc
        r = np.sqrt((dR**2).sum(axis=1))

        # mult each element and sum along the axis (vector dot product)
        m_dot_dR_div_r2 = (m * dR).sum(axis=1) / (r**2)

        # multiply the scalar m_dot_dR by the 3D vector r
        rvec_m_dot_dR_div_r2 = np.vstack([m_dot_dR_div_r2 * dR[:, i] for
                                          i in range(3)]).T
        inside = (3. * rvec_m_dot_dR_div_r2) - m

        # dot product with rx orientation
        inside_dot_rx = (inside * rx).sum(axis=1)
        front = (mu/(4.* np.pi * r**3))

        B.append(Utils.mkvc(front * inside_dot_rx))

    return np.vstack(B).T