Esempio n. 1
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)
Esempio n. 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)
Esempio n. 3
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

            :param numpy.array prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))
            :param str projType: 'E' or 'F'
            :param bool returnP: returns the projection matrices
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: scipy.sparse.csr_matrix
            :return: M, the inner product matrix (nF, nF)
        """
        assert projType in ['F', 'E'], ("projType must be 'F' for faces or 'E'"
                                        " for edges")

        if prop is None:
            prop = np.ones(self.nC)

        if invProp:
            prop = 1./prop

        if Utils.isScalar(prop):
            prop = prop*np.ones(self.nC)

        # number of elements we are averaging (equals dim for regular
        # meshes, but for cyl, where we use symmetry, it is 1 for edge
        # variables and 2 for face variables)
        if self._meshType == 'CYL':
            n_elements = np.sum(getattr(self, 'vn'+projType).nonzero())
        else:
            n_elements = self.dim

        # Isotropic? or anisotropic?
        if prop.size == self.nC:
            Av = getattr(self, 'ave'+projType+'2CC')
            Vprop = self.vol * Utils.mkvc(prop)
            M = n_elements * Utils.sdiag(Av.T * Vprop)

        elif prop.size == self.nC*self.dim:
            Av = getattr(self, 'ave'+projType+'2CCV')

            # if cyl, then only certain components are relevant due to symmetry
            # for faces, x, z matters, for edges, y (which is theta) matters
            if self._meshType == 'CYL':
                if projType == 'E':
                    prop = prop[:, 1] # this is the action of a projection mat
                elif projType == 'F':
                    prop = prop[:, [0, 2]]

            V = sp.kron(sp.identity(n_elements), Utils.sdiag(self.vol))
            M = Utils.sdiag(Av.T * V * Utils.mkvc(prop))
        else:
            return None

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Esempio n. 4
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

            :param numpy.array prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))
            :param str projType: 'E' or 'F'
            :param bool returnP: returns the projection matrices
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: scipy.sparse.csr_matrix
            :return: M, the inner product matrix (nF, nF)
        """
        assert projType in ["F", "E"], "projType must be 'F' for faces or 'E'" " for edges"

        if prop is None:
            prop = np.ones(self.nC)

        if invProp:
            prop = 1.0 / prop

        if Utils.isScalar(prop):
            prop = prop * np.ones(self.nC)

        # number of elements we are averaging (equals dim for regular
        # meshes, but for cyl, where we use symmetry, it is 1 for edge
        # variables and 2 for face variables)
        if self._meshType == "CYL":
            n_elements = np.sum(getattr(self, "vn" + projType).nonzero())
        else:
            n_elements = self.dim

        # Isotropic? or anisotropic?
        if prop.size == self.nC:
            Av = getattr(self, "ave" + projType + "2CC")
            Vprop = self.vol * Utils.mkvc(prop)
            M = n_elements * Utils.sdiag(Av.T * Vprop)

        elif prop.size == self.nC * self.dim:
            Av = getattr(self, "ave" + projType + "2CCV")

            # if cyl, then only certain components are relevant due to symmetry
            # for faces, x, z matters, for edges, y (which is theta) matters
            if self._meshType == "CYL":
                if projType == "E":
                    prop = prop[:, 1]  # this is the action of a projection mat
                elif projType == "F":
                    prop = prop[:, [0, 2]]

            V = sp.kron(sp.identity(n_elements), Utils.sdiag(self.vol))
            M = Utils.sdiag(Av.T * V * Utils.mkvc(prop))
        else:
            return None

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Esempio n. 5
0
def convertObs_DC3D_to_2D(Tx,Rx):
    
    from SimPEG import np
    import numpy.matlib as npm
    """
        Read list of 3D Tx Rx location and change coordinate system to distance
        along line assuming all data is acquired along line
        First transmitter pole is assumed to be at the origin

        Assumes flat topo for now...
    
        Input:
        :param Tx, Rx
        
        Output:
        :figure Tx2d, Rx2d
        
        Created on Mon December 7th, 2015
    
        @author: dominiquef
    
    """
    
                
    Tx2d = []
    Rx2d = []

    for ii in range(len(Tx)):
        
        if ii == 0:
            endp = Tx[0][0:2,0]
        
        nrx = Rx[ii].shape[0]
                  
        rP1 = np.sqrt( np.sum( ( endp - Tx[ii][0:2,0] )**2 , axis=0))
        rP2 = np.sqrt( np.sum( ( endp - Tx[ii][0:2,1] )**2 , axis=0))
        rC1 = np.sqrt( np.sum( ( npm.repmat(endp.T,nrx,1) - Rx[ii][:,0:2] )**2 , axis=1))
        rC2 = np.sqrt( np.sum( ( npm.repmat(endp.T,nrx,1) - Rx[ii][:,3:5] )**2 , axis=1))
        
        Tx2d.append( np.r_[rP1, rP2] )
        Rx2d.append( np.c_[rC1, rC2] )
            #np.savetxt(fid, data, fmt='%e',delimiter=' ',newline='\n')

    return Tx2d, Rx2d
Esempio n. 6
0
    def setUp(self):

        # Define inducing field and sphere parameters
        H0 = (50000., 60., 270.)
        self.b0 = PF.MagAnalytics.IDTtoxyz(-H0[1], H0[2], H0[0])
        self.rad = 2.
        self.chi = 0.01

        # Define a mesh
        cs = 0.2
        hxind = [(cs, 21)]
        hyind = [(cs, 21)]
        hzind = [(cs, 21)]
        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get cells inside the sphere
        sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., self.rad)

        # Adjust susceptibility for volume difference
        Vratio = (4. / 3. * np.pi * self.rad**3.) / (np.sum(sph_ind) * cs**3.)
        model = np.ones(mesh.nC) * self.chi * Vratio
        self.model = model[sph_ind]

        # Creat reduced identity map for Linear Pproblem
        idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

        # Create plane of observations
        xr = np.linspace(-20, 20, 21)
        yr = np.linspace(-20, 20, 21)
        X, Y = np.meshgrid(xr, yr)

        # Move obs plane 2 radius away from sphere
        Z = np.ones((xr.size, yr.size)) * 2. * self.rad
        self.locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        rxLoc = PF.BaseMag.RxObs(self.locXyz)
        srcField = PF.BaseMag.SrcField([rxLoc], param=H0)
        self.survey = PF.BaseMag.LinearSurvey(srcField)

        self.prob_xyz = PF.Magnetics.MagneticIntegral(mesh,
                                                      mapping=idenMap,
                                                      actInd=sph_ind,
                                                      forwardOnly=True,
                                                      rtype='xyz')

        self.prob_tmi = PF.Magnetics.MagneticIntegral(mesh,
                                                      mapping=idenMap,
                                                      actInd=sph_ind,
                                                      forwardOnly=True,
                                                      rtype='tmi')
Esempio n. 7
0
    def setUp(self):

        # Define sphere parameters
        self.rad = 2.
        self.rho = 0.1

        # Define a mesh
        cs = 0.2
        hxind = [(cs, 21)]
        hyind = [(cs, 21)]
        hzind = [(cs, 21)]
        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get cells inside the sphere
        sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., self.rad)

        # Adjust density for volume difference
        Vratio = (4. / 3. * np.pi * self.rad**3.) / (np.sum(sph_ind) * cs**3.)
        model = np.ones(mesh.nC) * self.rho * Vratio
        self.model = model[sph_ind]

        # Create reduced identity map for Linear Pproblem
        idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

        # Create plane of observations
        xr = np.linspace(-20, 20, 21)
        yr = np.linspace(-20, 20, 21)
        X, Y = np.meshgrid(xr, yr)

        # Move obs plane 2 radius away from sphere
        Z = np.ones((xr.size, yr.size)) * 2. * self.rad
        self.locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        rxLoc = PF.BaseGrav.RxObs(self.locXyz)
        srcField = PF.BaseGrav.SrcField([rxLoc])
        self.survey = PF.BaseGrav.LinearSurvey(srcField)

        self.prob_xyz = PF.Gravity.GravityIntegral(mesh,
                                                   mapping=idenMap,
                                                   actInd=sph_ind,
                                                   forwardOnly=True,
                                                   rtype='xyz')

        self.prob_z = PF.Gravity.GravityIntegral(mesh,
                                                 mapping=idenMap,
                                                 actInd=sph_ind,
                                                 forwardOnly=True,
                                                 rtype='z')
Esempio n. 8
0
    def setUp(self):

        # Define inducing field and sphere parameters
        H0 = (50000., 60., 270.)
        self.b0 = PF.MagAnalytics.IDTtoxyz(-H0[1], H0[2], H0[0])
        self.rad = 2.
        self.chi = 0.01

        # Define a mesh
        cs = 0.2
        hxind = [(cs, 21)]
        hyind = [(cs, 21)]
        hzind = [(cs, 21)]
        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get cells inside the sphere
        sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., self.rad)

        # Adjust susceptibility for volume difference
        Vratio = (4./3.*np.pi*self.rad**3.) / (np.sum(sph_ind)*cs**3.)
        model = np.ones(mesh.nC)*self.chi*Vratio
        self.model = model[sph_ind]

        # Creat reduced identity map for Linear Pproblem
        idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

        # Create plane of observations
        xr = np.linspace(-20, 20, 21)
        yr = np.linspace(-20, 20, 21)
        X, Y = np.meshgrid(xr, yr)

        # Move obs plane 2 radius away from sphere
        Z = np.ones((xr.size, yr.size))*2.*self.rad
        self.locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        rxLoc = PF.BaseMag.RxObs(self.locXyz)
        srcField = PF.BaseMag.SrcField([rxLoc], param=H0)
        self.survey = PF.BaseMag.LinearSurvey(srcField)

        self.prob_xyz = PF.Magnetics.MagneticIntegral(mesh, mapping=idenMap,
                                                      actInd=sph_ind,
                                                      forwardOnly=True,
                                                      rtype='xyz')

        self.prob_tmi = PF.Magnetics.MagneticIntegral(mesh, mapping=idenMap,
                                                      actInd=sph_ind,
                                                      forwardOnly=True,
                                                      rtype='tmi')
Esempio n. 9
0
    def setUp(self):

        # Define sphere parameters
        self.rad = 2.
        self.rho = 0.1

        # Define a mesh
        cs = 0.2
        hxind = [(cs, 21)]
        hyind = [(cs, 21)]
        hzind = [(cs, 21)]
        mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

        # Get cells inside the sphere
        sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., self.rad)

        # Adjust density for volume difference
        Vratio = (4./3.*np.pi*self.rad**3.) / (np.sum(sph_ind)*cs**3.)
        model = np.ones(mesh.nC)*self.rho*Vratio
        self.model = model[sph_ind]

        # Create reduced identity map for Linear Pproblem
        idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

        # Create plane of observations
        xr = np.linspace(-20, 20, 21)
        yr = np.linspace(-20, 20, 21)
        X, Y = np.meshgrid(xr, yr)

        # Move obs plane 2 radius away from sphere
        Z = np.ones((xr.size, yr.size))*2.*self.rad
        self.locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        rxLoc = PF.BaseGrav.RxObs(self.locXyz)
        srcField = PF.BaseGrav.SrcField([rxLoc])
        self.survey = PF.BaseGrav.LinearSurvey(srcField)

        self.prob_xyz = PF.Gravity.GravityIntegral(mesh, mapping=idenMap,
                                                   actInd=sph_ind,
                                                   forwardOnly=True,
                                                   rtype='xyz')

        self.prob_z = PF.Gravity.GravityIntegral(mesh, mapping=idenMap,
                                                 actInd=sph_ind,
                                                 forwardOnly=True,
                                                 rtype='z')
Esempio n. 10
0
ii = 1
ddata = 9999.

while ddata > 2.:

    ii += 1

    indx = np.unravel_index(bc, (mesh.nCx, mesh.nCy, mesh.nCz), order='F')

    xbreak = np.unique(indx[0])
    ybreak = np.unique(indx[1])
    zbreak = np.unique(indx[2])

    # Compute the new distance
    dl = np.sum(hxind[xbreak])
    dx = float(hxind[xbreak].min() / 2)
    nx = dl / dx

    hxind = np.r_[hxind[0:xbreak.min()],
                  np.ones(nx) * dx, hxind[xbreak.max():]]

    dl = np.sum(hyind[ybreak])
    dy = float(hyind[ybreak].min() / 2)
    ny = dl / dy

    hyind = np.r_[hyind[0:ybreak.min()],
                  np.ones(ny) * dy, hyind[ybreak.max():]]

    dl = np.sum(hzind[zbreak])
    dz = float(hzind[zbreak].min() / 2)
Esempio n. 11
0
ylim = (546000, 546750)
xlim = (422900, 423675)
# Takes two points from ginput and create survey
temp = plt.ginput(2)

# Add z coordinate
nz = mesh.vectorNz
endp = np.c_[np.asarray(temp), np.ones(2).T * nz[-1]]

# Create dipole survey receivers and plot
nrx = 10
ab = 40
a = 20

# Evenly distribute transmitters for now and put on surface
dplen = np.sqrt(np.sum((endp[1, :] - endp[0, :])**2))
dp_x = (endp[1, 0] - endp[0, 0]) / dplen
dp_y = (endp[1, 1] - endp[0, 1]) / dplen

nstn = np.floor(dplen / ab)

stn_x = endp[0, 0] + np.cumsum(np.ones(nstn) * dp_x * ab)
stn_y = endp[0, 1] + np.cumsum(np.ones(nstn) * dp_y * ab)

plt.scatter(stn_x, stn_y, s=100, c='w')

M = np.c_[stn_x - a * dp_x, stn_y - a * dp_y, np.ones(nstn).T * nz[-1]]
N = np.c_[stn_x + a * dp_x, stn_y + a * dp_y, np.ones(nstn).T * nz[-1]]

plt.scatter(M[:, 0], M[:, 1], s=10, c='r')
plt.scatter(N[:, 0], N[:, 1], s=10, c='b')
Esempio n. 12
0
 def xy_2_r(x1, x2, y1, y2):
     r = np.sqrt(np.sum((x2 - x1)**2 + (y2 - y1)**2))
     return r
Esempio n. 13
0
def _r2(xyz):
    return np.sum(xyz**2,1)
Esempio n. 14
0
    def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False):
        """
            :param str projType: 'E' or 'F'
            :param TensorType tensorType: type of the tensor
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: function
            :return: dMdmu, the derivative of the inner product matrix
        """
        assert projType in ["F", "E"], "projType must be 'F' for faces or 'E'" " for edges"

        tensorType = Utils.TensorType(self, prop)

        dMdprop = None

        if invMat or invProp:
            MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat)

        # number of elements we are averaging (equals dim for regular
        # meshes, but for cyl, where we use symmetry, it is 1 for edge
        # variables and 2 for face variables)
        if self._meshType == "CYL":
            n_elements = np.sum(getattr(self, "vn" + projType).nonzero())
        else:
            n_elements = self.dim

        if tensorType == 0:  # isotropic, constant
            Av = getattr(self, "ave" + projType + "2CC")
            V = Utils.sdiag(self.vol)
            ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC), np.zeros(self.nC))), shape=(self.nC, 1))
            if not invMat and not invProp:
                dMdprop = n_elements * Av.T * V * ones
            elif invMat and invProp:
                dMdprop = n_elements * (
                    Utils.sdiag(MI.diagonal() ** 2) * Av.T * V * ones * Utils.sdiag(1.0 / prop ** 2)
                )
            elif invProp:
                dMdprop = n_elements * Av.T * V * Utils.sdiag(-1.0 / prop ** 2)
            elif invMat:
                dMdprop = n_elements * (Utils.sdiag(-MI.diagonal() ** 2) * Av.T * V)

        elif tensorType == 1:  # isotropic, variable in space
            Av = getattr(self, "ave" + projType + "2CC")
            V = Utils.sdiag(self.vol)
            if not invMat and not invProp:
                dMdprop = n_elements * Av.T * V
            elif invMat and invProp:
                dMdprop = n_elements * (Utils.sdiag(MI.diagonal() ** 2) * Av.T * V * Utils.sdiag(1.0 / prop ** 2))
            elif invProp:
                dMdprop = n_elements * Av.T * V * Utils.sdiag(-1.0 / prop ** 2)
            elif invMat:
                dMdprop = n_elements * (Utils.sdiag(-MI.diagonal() ** 2) * Av.T * V)

        elif tensorType == 2:  # anisotropic
            Av = getattr(self, "ave" + projType + "2CCV")
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))

            if self._meshType == "CYL":
                Zero = sp.csr_matrix((self.nC, self.nC))
                Eye = sp.eye(self.nC)
                if projType == "E":
                    P = sp.hstack([Zero, Eye, Zero])
                    # print(P.todense())
                elif projType == "F":
                    P = sp.vstack([sp.hstack([Eye, Zero, Zero]), sp.hstack([Zero, Zero, Eye])])
                    # print(P.todense())
            else:
                P = sp.eye(self.nC * self.dim)

            if not invMat and not invProp:
                dMdprop = Av.T * P * V
            elif invMat and invProp:
                dMdprop = Utils.sdiag(MI.diagonal() ** 2) * Av.T * P * V * Utils.sdiag(1.0 / prop ** 2)
            elif invProp:
                dMdprop = Av.T * P * V * Utils.sdiag(-1.0 / prop ** 2)
            elif invMat:
                dMdprop = Utils.sdiag(-MI.diagonal() ** 2) * Av.T * P * V

        if dMdprop is not None:

            def innerProductDeriv(v=None):
                if v is None:
                    warnings.warn(
                        "Depreciation Warning: "
                        "TensorMesh.innerProductDeriv."
                        " You should be supplying a vector. "
                        "Use: sdiag(u)*dMdprop",
                        FutureWarning,
                    )
                    return dMdprop
                return Utils.sdiag(v) * dMdprop

            return innerProductDeriv
        else:
            return None
Esempio n. 15
0
def run(plotIt=True):
    """
        MT: 1D: Inversion
        =================

        Forward model 1D MT data.
        Setup and run a MT 1D inversion.

    """

    ## Setup the forward modeling
    # Setting up 1D mesh and conductivity models to forward model data.
    # Frequency
    nFreq = 26
    freqs = np.logspace(2, -3, nFreq)
    # Set mesh parameters
    ct = 10
    air = simpeg.Utils.meshTensor([(ct, 25, 1.4)])
    core = np.concatenate(
        (np.kron(simpeg.Utils.meshTensor([(ct, 10, -1.3)]), np.ones(
            (5, ))), simpeg.Utils.meshTensor([(ct, 5)])))
    bot = simpeg.Utils.meshTensor([(core[0], 25, -1.4)])
    x0 = -np.array([np.sum(np.concatenate((core, bot)))])
    # Make the model
    m1d = simpeg.Mesh.TensorMesh([np.concatenate((bot, core, air))], x0=x0)

    # Setup model varibles
    active = m1d.vectorCCx < 0.
    layer1 = (m1d.vectorCCx < -500.) & (m1d.vectorCCx >= -800.)
    layer2 = (m1d.vectorCCx < -3500.) & (m1d.vectorCCx >= -5000.)
    # Set the conductivity values
    sig_half = 1e-2
    sig_air = 1e-8
    sig_layer1 = .2
    sig_layer2 = .2
    # Make the true model
    sigma_true = np.ones(m1d.nCx) * sig_air
    sigma_true[active] = sig_half
    sigma_true[layer1] = sig_layer1
    sigma_true[layer2] = sig_layer2
    # Extract the model
    m_true = np.log(sigma_true[active])
    # Make the background model
    sigma_0 = np.ones(m1d.nCx) * sig_air
    sigma_0[active] = sig_half
    m_0 = np.log(sigma_0[active])

    # Set the mapping
    actMap = simpeg.Maps.InjectActiveCells(m1d,
                                           active,
                                           np.log(1e-8),
                                           nC=m1d.nCx)
    mappingExpAct = simpeg.Maps.ExpMap(m1d) * actMap

    ## Setup the layout of the survey, set the sources and the connected receivers
    # Receivers
    rxList = []
    rxList.append(
        NSEM.Rx.Point_impedance1D(simpeg.mkvc(np.array([-0.5]), 2).T, 'real'))
    rxList.append(
        NSEM.Rx.Point_impedance1D(simpeg.mkvc(np.array([-0.5]), 2).T, 'imag'))
    # Source list
    srcList = []
    for freq in freqs:
        srcList.append(NSEM.Src.Planewave_xy_1Dprimary(rxList, freq))
    # Make the survey
    survey = NSEM.Survey(srcList)
    survey.mtrue = m_true

    ## Set the problem
    problem = NSEM.Problem1D_ePrimSec(m1d,
                                      sigmaPrimary=sigma_0,
                                      mapping=mappingExpAct)
    problem.pair(survey)

    ## Forward model data
    # Project the data
    survey.dtrue = survey.dpred(m_true)
    survey.dobs = survey.dtrue + 0.01 * abs(
        survey.dtrue) * np.random.randn(*survey.dtrue.shape)

    if plotIt:
        fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem, [])
        fig.suptitle('Target - smooth true')

    # Assign uncertainties
    std = 0.05  # 5% std
    survey.std = np.abs(survey.dobs * std)
    # Assign the data weight
    Wd = 1. / survey.std

    ## Setup the inversion proceedure
    # Define a counter
    C = simpeg.Utils.Counter()
    # Set the optimization
    opt = simpeg.Optimization.ProjectedGNCG(maxIter=25)
    opt.counter = C
    opt.lower = np.log(1e-4)
    opt.upper = np.log(5)
    opt.LSshorten = 0.1
    opt.remember('xc')
    # Data misfit
    dmis = simpeg.DataMisfit.l2_DataMisfit(survey)
    dmis.Wd = Wd
    # Regularization - with a regularization mesh
    regMesh = simpeg.Mesh.TensorMesh([m1d.hx[active]], m1d.x0)
    reg = simpeg.Regularization.Tikhonov(regMesh)
    reg.mrefInSmooth = True
    reg.alpha_s = 1e-1
    reg.alpha_x = 1.

    # Inversion problem
    invProb = simpeg.InvProblem.BaseInvProblem(dmis, reg, opt)
    invProb.counter = C
    # Beta cooling
    beta = simpeg.Directives.BetaSchedule()
    beta.coolingRate = 4.
    beta.coolingFactor = 4.
    betaest = simpeg.Directives.BetaEstimate_ByEig(beta0_ratio=100.)
    betaest.beta0 = 1.
    targmis = simpeg.Directives.TargetMisfit()
    targmis.target = survey.nD
    # Create an inversion object
    inv = simpeg.Inversion.BaseInversion(
        invProb, directiveList=[beta, betaest, targmis])

    ## Run the inversion
    mopt = inv.run(m_0)

    if plotIt:
        fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem, [mopt])
        fig.suptitle('Target - smooth true')
        fig.axes[0].set_ylim([-10000, 500])
        plt.show()
Esempio n. 16
0
    def _fastInnerProductDeriv(self, projType, prop, invProp=False,
                               invMat=False):
        """
            :param str projType: 'E' or 'F'
            :param TensorType tensorType: type of the tensor
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: function
            :return: dMdmu, the derivative of the inner product matrix
        """
        assert projType in ['F', 'E'], ("projType must be 'F' for faces or 'E'"
                                        " for edges")

        tensorType = Utils.TensorType(self, prop)

        dMdprop = None

        if invMat or invProp:
            MI = self._fastInnerProduct(projType, prop, invProp=invProp,
                                        invMat=invMat)

        # number of elements we are averaging (equals dim for regular
        # meshes, but for cyl, where we use symmetry, it is 1 for edge
        # variables and 2 for face variables)
        if self._meshType == 'CYL':
            n_elements = np.sum(getattr(self, 'vn'+projType).nonzero())
        else:
            n_elements = self.dim


        if tensorType == 0:  # isotropic, constant
            Av = getattr(self, 'ave'+projType+'2CC')
            V = Utils.sdiag(self.vol)
            ones = sp.csr_matrix((np.ones(self.nC), (range(self.nC),
                                                     np.zeros(self.nC))),
                                 shape=(self.nC, 1))
            if not invMat and not invProp:
                dMdprop = n_elements * Av.T * V * ones
            elif invMat and invProp:
                dMdprop =  n_elements * (Utils.sdiag(MI.diagonal()**2) * Av.T *
                                         V * ones * Utils.sdiag(1./prop**2))
            elif invProp:
                dMdprop = n_elements * Av.T * V * Utils.sdiag(- 1./prop**2)
            elif invMat:
                dMdprop = n_elements * (Utils.sdiag(- MI.diagonal()**2) * Av.T
                                        * V)

        elif tensorType == 1:  # isotropic, variable in space
            Av = getattr(self, 'ave'+projType+'2CC')
            V = Utils.sdiag(self.vol)
            if not invMat and not invProp:
                dMdprop = n_elements * Av.T * V
            elif invMat and invProp:
                dMdprop =  n_elements * (Utils.sdiag(MI.diagonal()**2) * Av.T *
                                         V * Utils.sdiag(1./prop**2))
            elif invProp:
                dMdprop = n_elements * Av.T * V * Utils.sdiag(-1./prop**2)
            elif invMat:
                dMdprop = n_elements * (Utils.sdiag(- MI.diagonal()**2) * Av.T
                                        * V)

        elif tensorType == 2: # anisotropic
            Av = getattr(self, 'ave'+projType+'2CCV')
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))

            if self._meshType == 'CYL':
                Zero = sp.csr_matrix((self.nC, self.nC))
                Eye = sp.eye(self.nC)
                if projType == 'E':
                    P = sp.hstack([Zero, Eye, Zero])
                    # print P.todense()
                elif projType == 'F':
                    P = sp.vstack([sp.hstack([Eye, Zero, Zero]),
                                   sp.hstack([Zero, Zero, Eye])])
                    # print P.todense()
            else:
                P = sp.eye(self.nC*self.dim)

            if not invMat and not invProp:
                dMdprop = Av.T * P * V
            elif invMat and invProp:
                dMdprop = (Utils.sdiag(MI.diagonal()**2) * Av.T * P * V *
                           Utils.sdiag(1./prop**2))
            elif invProp:
                dMdprop = Av.T * P * V * Utils.sdiag(-1./prop**2)
            elif invMat:
                dMdprop = Utils.sdiag(- MI.diagonal()**2) * Av.T * P * V

        if dMdprop is not None:
            def innerProductDeriv(v=None):
                if v is None:
                    warnings.warn("Depreciation Warning: "
                                  "TensorMesh.innerProductDeriv."
                                  " You should be supplying a vector. "
                                  "Use: sdiag(u)*dMdprop", FutureWarning)
                    return dMdprop
                return Utils.sdiag(v) * dMdprop
            return innerProductDeriv
        else:
            return None
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True):
    """
        DC Forward Simulation
        =====================

        Forward model conductive spheres in a half-space and plot a pseudo-section

        Created by @fourndo on Mon Feb 01 19:28:06 2016

    """

    assert stype in ['pdp', 'dpdp'], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)"


    if loc is None:
        loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]]
    if sig is None:
        sig = np.r_[1e-2,1e-1,1e-3]
    if radi is None:
        radi = np.r_[25.,25.]
    if param is None:
        param = np.r_[30.,30.,5]


    # First we need to create a mesh and a model.

    # This is our mesh
    dx    = 5.

    hxind = [(dx,15,-1.3), (dx, 75), (dx,15,1.3)]
    hyind = [(dx,15,-1.3), (dx, 10), (dx,15,1.3)]
    hzind = [(dx,15,-1.3),(dx, 15)]

    mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')


    # Set background conductivity
    model = np.ones(mesh.nC) * sig[0]

    # First anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:,0],radi[0],mesh.gridCC)
    model[ind] = sig[1]

    # Second anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:,1],radi[1],mesh.gridCC)
    model[ind] = sig[2]

    # Get index of the center
    indy = int(mesh.nCy/2)


    # Plot the model for reference
    # Define core mesh extent
    xlim = 200
    zlim = 125

    # Specify the survey type: "pdp" | "dpdp"


    # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh
    ends = [(-175,0),(175,0)]
    ends = np.c_[np.asarray(ends),np.ones(2).T*mesh.vectorNz[-1]]

    # Snap the endpoints to the grid. Easier to create 2D section.
    indx = Utils.closestPoints(mesh, ends )
    locs = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*mesh.vectorNz[-1]]

    # We will handle the geometry of the survey for you and create all the combination of tx-rx along line
    # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])
    survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])

    # Define some global geometry
    dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) )
    dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len
    dl_y = ( Tx[-1][1,1] - Tx[0][1,0]  ) / dl_len
    azm =  np.arctan(dl_y/dl_x)

    #Set boundary conditions
    mesh.setCellGradBC('neumann')

    # Define the differential operators needed for the DC problem
    Div = mesh.faceDiv
    Grad = mesh.cellGrad
    Msig = Utils.sdiag(1./(mesh.aveF2CC.T*(1./model)))

    A = Div*Msig*Grad

    # Change one corner to deal with nullspace
    A[0,0] = 1
    A = sp.csc_matrix(A)

    # We will solve the system iteratively, so a pre-conditioner is helpful
    # This is simply a Jacobi preconditioner (inverse of the main diagonal)
    dA = A.diagonal()
    P = sp.spdiags(1/dA,0,A.shape[0],A.shape[0])

    # Now we can solve the system for all the transmitters
    # We want to store the data
    data = []

    # There is probably a more elegant way to do this, but we can just for-loop through the transmitters
    for ii in range(len(Tx)):

        start_time = time.time() # Let's time the calculations

        #print("Transmitter %i / %i\r" % (ii+1,len(Tx)))

        # Select dipole locations for receiver
        rxloc_M = np.asarray(Rx[ii][:,0:3])
        rxloc_N = np.asarray(Rx[ii][:,3:])


        # For usual cases "dpdp" or "gradient"
        if stype == 'pdp':
            # Create an "inifinity" pole
            tx =  np.squeeze(Tx[ii][:,0:1])
            tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2
            inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1] / mesh.vol[inds] )
        else:
            inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T )
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1,1] / mesh.vol[inds] )

        # Iterative Solve
        Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5)

        # We now have the potential everywhere
        phi = Utils.mkvc(Ainvb[0])

        # Solve for phi on pole locations
        P1 = mesh.getInterpolationMat(rxloc_M, 'CC')
        P2 = mesh.getInterpolationMat(rxloc_N, 'CC')

        # Compute the potential difference
        dtemp = (P1*phi - P2*phi)*np.pi

        data.append( dtemp )
        print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time),

    print 'Transmitter {0} of {1}'.format(ii,len(Tx))
    print 'Forward completed'

    # Let's just convert the 3D format into 2D (distance along line) and plot
    # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D.dobs =np.hstack(data)
    # Here is an example for the first tx-rx array
    if plotIt:
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = plt.subplot(2,1,1, aspect='equal')
        mesh.plotSlice(np.log10(model), ax =ax, normal = 'Y', ind = indy,grid=True)
        ax.set_title('E-W section at '+str(mesh.vectorCCy[indy])+' m')
        plt.gca().set_aspect('equal', adjustable='box')

        plt.scatter(Tx[0][0,:],Tx[0][2,:],s=40,c='g', marker='v')
        plt.scatter(Rx[0][:,0::3],Rx[0][:,2::3],s=40,c='y')
        plt.xlim([-xlim,xlim])
        plt.ylim([-zlim,mesh.vectorNz[-1]+dx])


        ax = plt.subplot(2,1,2, aspect='equal')

        # Plot the location of the spheres for reference
        circle1=plt.Circle((loc[0,0]-Tx[0][0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3)
        circle2=plt.Circle((loc[0,1]-Tx[0][0,0],loc[2,1]),radi[1],color='k',fill=False, lw=3)
        ax.add_artist(circle1)
        ax.add_artist(circle2)

        # Add the speudo section
        DC.plot_pseudoSection(survey2D,ax,stype)

        # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
        # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y')
        # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k')
        plt.ylim([-zlim,mesh.vectorNz[-1]+dx])

        plt.show()

        return fig, ax
Esempio n. 18
0
b0 = PF.MagAnalytics.IDTtoxyz(-H0[1], H0[2], H0[0])
rad = 2.
chi = 0.01

# Define a mesh
cs = 0.2
hxind = [(cs,10,1.3),(cs, 21),(cs,10,1.3)]
hyind = [(cs,10,1.3),(cs, 21),(cs,10,1.3)]
hzind = [(cs,10,1.3),(cs, 21),(cs,10,1.3)]
mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

# Get cells inside the sphere
sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., rad)

# Adjust susceptibility for volume difference
Vratio = (4./3.*np.pi*rad**3.) / (np.sum(sph_ind)*cs**3.)
model = np.zeros(mesh.nC)
model[sph_ind] = chi*Vratio
m = model[sph_ind]

# Creat reduced identity map for Linear Pproblem
idenMap = Maps.IdentityMap(nP=int(sum(sph_ind)))

# Create plane of observations
xr = np.linspace(-10, 10, 21)
yr = np.linspace(-10, 10, 21)
X, Y = np.meshgrid(xr, yr)

# Move obs plane 2 radius away from sphere
Z = np.ones((xr.size, yr.size))*2.*rad
locXyz = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
Esempio n. 19
0
H0 = (50000., 60., 270.)
rad = 2.
rho = 0.1

# Define a mesh
cs = 0.5
hxind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)]
hyind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)]
hzind = [(cs, 5, -1.3), (cs, 9), (cs, 5, 1.3)]
mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCC')

# Get cells inside the sphere
sph_ind = PF.MagAnalytics.spheremodel(mesh, 0., 0., 0., rad)

# Adjust susceptibility for volume difference
Vratio = (4. / 3. * np.pi * rad**3.) / (np.sum(sph_ind) * cs**3.)
model = np.ones(mesh.nC) * 1e-8
model[sph_ind] = 0.01

rxLoc = np.asarray([np.r_[0, 0, 4.]])

bzi = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'real')
bzr = FDEM.Rx.Point_bSecondary(rxLoc, 'z', 'imag')

freqs = [400]  #np.logspace(2, 3, 5)
srcLoc = np.r_[0, 0, 4.]

srcList = [
    FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z')
    for freq in freqs
]
Esempio n. 20
0
 def xy_2_r(x1,x2,y1,y2):
     r = np.sqrt( np.sum((x2 - x1)**2 + (y2 - y1)**2) )
     return r 
Esempio n. 21
0
def _r2(xyz):
    return np.sum(xyz**2, 1)
Esempio n. 22
0
#
#%% Create dcin2d inversion files and run
dx = 20.

dl_len = np.max(srcMat[lineID == 0, 0, 0]) - np.min(srcMat[lineID == 0, 0, 0])
nc = np.ceil(dl_len / dx) + 10

padx = dx * np.power(1.4, range(1, padc))

# Creating padding cells
hx = np.r_[padx[::-1], np.ones(nc) * dx, padx]
hz = np.r_[padx[::-1], np.ones(int(nc / 5)) * dx]

# Create mesh with 0 coordinate centerer on the ginput points in cell center
mesh2d = Mesh.TensorMesh([hx, hz],
                         x0=(-np.sum(padx) + np.min(srcMat[0][:, 0]),
                             np.ceil(np.max(srcMat[0][0, 2])) - np.sum(hz)))

inv_dir = home_dir + '\Inv2D'
if not os.path.exists(inv_dir):
    os.makedirs(inv_dir)

mshfile2d = 'Mesh_2D.msh'
modfile2d = 'MtIsa_2D.con'
obsfile2d = 'FWR_3D_2_2D.dat'
ipfile2d = 'IP_2D.dat'
inp_file = 'dcinv2d.inp'

ini_mod = 1e-2
ref_mod = 1e-2
Esempio n. 23
0
def run(plotIt=True):
    """
        MT: 1D: Inversion
        =================

        Forward model 1D MT data.
        Setup and run a MT 1D inversion.

    """

    ## Setup the forward modeling
    # Setting up 1D mesh and conductivity models to forward model data.
    # Frequency
    nFreq = 26
    freqs = np.logspace(2,-3,nFreq)
    # Set mesh parameters
    ct = 10
    air = simpeg.Utils.meshTensor([(ct,25,1.4)])
    core = np.concatenate( (  np.kron(simpeg.Utils.meshTensor([(ct,10,-1.3)]),np.ones((5,))) , simpeg.Utils.meshTensor([(ct,5)]) ) )
    bot = simpeg.Utils.meshTensor([(core[0],25,-1.4)])
    x0 = -np.array([np.sum(np.concatenate((core,bot)))])
    # Make the model
    m1d = simpeg.Mesh.TensorMesh([np.concatenate((bot,core,air))], x0=x0)

    # Setup model varibles
    active = m1d.vectorCCx<0.
    layer1 = (m1d.vectorCCx<-500.) & (m1d.vectorCCx>=-800.)
    layer2 = (m1d.vectorCCx<-3500.) & (m1d.vectorCCx>=-5000.)
    # Set the conductivity values
    sig_half = 1e-2
    sig_air = 1e-8
    sig_layer1 = .2
    sig_layer2 = .2
    # Make the true model
    sigma_true = np.ones(m1d.nCx)*sig_air
    sigma_true[active] = sig_half
    sigma_true[layer1] = sig_layer1
    sigma_true[layer2] = sig_layer2
    # Extract the model
    m_true = np.log(sigma_true[active])
    # Make the background model
    sigma_0 = np.ones(m1d.nCx)*sig_air
    sigma_0[active] = sig_half
    m_0 = np.log(sigma_0[active])

    # Set the mapping
    actMap = simpeg.Maps.InjectActiveCells(m1d, active, np.log(1e-8), nC=m1d.nCx)
    mappingExpAct = simpeg.Maps.ExpMap(m1d) * actMap

    ## Setup the layout of the survey, set the sources and the connected receivers
    # Receivers
    rxList = []
    rxList.append(NSEM.Rx.Point_impedance1D(simpeg.mkvc(np.array([-0.5]),2).T,'real'))
    rxList.append(NSEM.Rx.Point_impedance1D(simpeg.mkvc(np.array([-0.5]),2).T,'imag'))
    # Source list
    srcList =[]
    for freq in freqs:
            srcList.append(NSEM.Src.Planewave_xy_1Dprimary(rxList,freq))
    # Make the survey
    survey = NSEM.Survey(srcList)
    survey.mtrue = m_true

    ## Set the problem
    problem = NSEM.Problem1D_ePrimSec(m1d,sigmaPrimary=sigma_0,mapping=mappingExpAct)
    problem.pair(survey)

    ## Forward model data
    # Project the data
    survey.dtrue = survey.dpred(m_true)
    survey.dobs = survey.dtrue + 0.01*abs(survey.dtrue)*np.random.randn(*survey.dtrue.shape)

    if plotIt:
        fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem,[])
        fig.suptitle('Target - smooth true')


    # Assign uncertainties
    std = 0.05 # 5% std
    survey.std = np.abs(survey.dobs*std)
    # Assign the data weight
    Wd = 1./survey.std

    ## Setup the inversion proceedure
    # Define a counter
    C =  simpeg.Utils.Counter()
    # Set the optimization
    opt = simpeg.Optimization.ProjectedGNCG(maxIter = 25)
    opt.counter = C
    opt.lower = np.log(1e-4)
    opt.upper = np.log(5)
    opt.LSshorten = 0.1
    opt.remember('xc')
    # Data misfit
    dmis = simpeg.DataMisfit.l2_DataMisfit(survey)
    dmis.Wd = Wd
    # Regularization - with a regularization mesh
    regMesh = simpeg.Mesh.TensorMesh([m1d.hx[active]],m1d.x0)
    reg = simpeg.Regularization.Tikhonov(regMesh)
    reg.mrefInSmooth = True
    reg.alpha_s = 1e-1
    reg.alpha_x = 1.

    # Inversion problem
    invProb = simpeg.InvProblem.BaseInvProblem(dmis, reg, opt)
    invProb.counter = C
    # Beta cooling
    beta = simpeg.Directives.BetaSchedule()
    beta.coolingRate = 4.
    beta.coolingFactor = 4.
    betaest = simpeg.Directives.BetaEstimate_ByEig(beta0_ratio=100.)
    betaest.beta0 = 1.
    targmis = simpeg.Directives.TargetMisfit()
    targmis.target = survey.nD
    # Create an inversion object
    inv = simpeg.Inversion.BaseInversion(invProb, directiveList=[beta,betaest,targmis])

    ## Run the inversion
    mopt = inv.run(m_0)

    if plotIt:
        fig = NSEM.Utils.dataUtils.plotMT1DModelData(problem,[mopt])
        fig.suptitle('Target - smooth true')
        fig.axes[0].set_ylim([-10000,500])
        plt.show()
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True):
    """
        DC Forward Simulation
        =====================

        Forward model conductive spheres in a half-space and plot a pseudo-section

        Created by @fourndo on Mon Feb 01 19:28:06 2016

    """

    assert stype in [
        'pdp', 'dpdp'
    ], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)"

    if loc is None:
        loc = np.c_[[-50., 0., -50.], [50., 0., -50.]]
    if sig is None:
        sig = np.r_[1e-2, 1e-1, 1e-3]
    if radi is None:
        radi = np.r_[25., 25.]
    if param is None:
        param = np.r_[30., 30., 5]

    # First we need to create a mesh and a model.

    # This is our mesh
    dx = 5.

    hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)]
    hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)]
    hzind = [(dx, 15, -1.3), (dx, 15)]

    mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')

    # Set background conductivity
    model = np.ones(mesh.nC) * sig[0]

    # First anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC)
    model[ind] = sig[1]

    # Second anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC)
    model[ind] = sig[2]

    # Get index of the center
    indy = int(mesh.nCy / 2)

    # Plot the model for reference
    # Define core mesh extent
    xlim = 200
    zlim = 125

    # Specify the survey type: "pdp" | "dpdp"

    # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh
    ends = [(-175, 0), (175, 0)]
    ends = np.c_[np.asarray(ends), np.ones(2).T * mesh.vectorNz[-1]]

    # Snap the endpoints to the grid. Easier to create 2D section.
    indx = Utils.closestPoints(mesh, ends)
    locs = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1],
                 np.ones(2).T * mesh.vectorNz[-1]]

    # We will handle the geometry of the survey for you and create all the combination of tx-rx along line
    # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])
    survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1],
                                       param[2])

    # Define some global geometry
    dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2))
    dl_x = (Tx[-1][0, 1] - Tx[0][0, 0]) / dl_len
    dl_y = (Tx[-1][1, 1] - Tx[0][1, 0]) / dl_len
    azm = np.arctan(dl_y / dl_x)

    #Set boundary conditions
    mesh.setCellGradBC('neumann')

    # Define the differential operators needed for the DC problem
    Div = mesh.faceDiv
    Grad = mesh.cellGrad
    Msig = Utils.sdiag(1. / (mesh.aveF2CC.T * (1. / model)))

    A = Div * Msig * Grad

    # Change one corner to deal with nullspace
    A[0, 0] = 1
    A = sp.csc_matrix(A)

    # We will solve the system iteratively, so a pre-conditioner is helpful
    # This is simply a Jacobi preconditioner (inverse of the main diagonal)
    dA = A.diagonal()
    P = sp.spdiags(1 / dA, 0, A.shape[0], A.shape[0])

    # Now we can solve the system for all the transmitters
    # We want to store the data
    data = []

    # There is probably a more elegant way to do this, but we can just for-loop through the transmitters
    for ii in range(len(Tx)):

        start_time = time.time()  # Let's time the calculations

        #print("Transmitter %i / %i\r" % (ii+1,len(Tx)))

        # Select dipole locations for receiver
        rxloc_M = np.asarray(Rx[ii][:, 0:3])
        rxloc_N = np.asarray(Rx[ii][:, 3:])

        # For usual cases "dpdp" or "gradient"
        if stype == 'pdp':
            # Create an "inifinity" pole
            tx = np.squeeze(Tx[ii][:, 0:1])
            tinf = tx + np.array([dl_x, dl_y, 0]) * dl_len * 2
            inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T,
                                           'CC').T * ([-1] / mesh.vol[inds])
        else:
            inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T,
                                           'CC').T * ([-1, 1] / mesh.vol[inds])

        # Iterative Solve
        Ainvb = sp.linalg.bicgstab(P * A, P * RHS, tol=1e-5)

        # We now have the potential everywhere
        phi = Utils.mkvc(Ainvb[0])

        # Solve for phi on pole locations
        P1 = mesh.getInterpolationMat(rxloc_M, 'CC')
        P2 = mesh.getInterpolationMat(rxloc_N, 'CC')

        # Compute the potential difference
        dtemp = (P1 * phi - P2 * phi) * np.pi

        data.append(dtemp)
        print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(
            ii, len(Tx),
            time.time() - start_time),

    print 'Transmitter {0} of {1}'.format(ii, len(Tx))
    print 'Forward completed'

    # Let's just convert the 3D format into 2D (distance along line) and plot
    # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D.dobs = np.hstack(data)
    # Here is an example for the first tx-rx array
    if plotIt:
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = plt.subplot(2, 1, 1, aspect='equal')
        mesh.plotSlice(np.log10(model), ax=ax, normal='Y', ind=indy, grid=True)
        ax.set_title('E-W section at ' + str(mesh.vectorCCy[indy]) + ' m')
        plt.gca().set_aspect('equal', adjustable='box')

        plt.scatter(Tx[0][0, :], Tx[0][2, :], s=40, c='g', marker='v')
        plt.scatter(Rx[0][:, 0::3], Rx[0][:, 2::3], s=40, c='y')
        plt.xlim([-xlim, xlim])
        plt.ylim([-zlim, mesh.vectorNz[-1] + dx])

        ax = plt.subplot(2, 1, 2, aspect='equal')

        # Plot the location of the spheres for reference
        circle1 = plt.Circle((loc[0, 0] - Tx[0][0, 0], loc[2, 0]),
                             radi[0],
                             color='w',
                             fill=False,
                             lw=3)
        circle2 = plt.Circle((loc[0, 1] - Tx[0][0, 0], loc[2, 1]),
                             radi[1],
                             color='k',
                             fill=False,
                             lw=3)
        ax.add_artist(circle1)
        ax.add_artist(circle2)

        # Add the speudo section
        DC.plot_pseudoSection(survey2D, ax, stype)

        # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
        # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y')
        # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k')
        plt.ylim([-zlim, mesh.vectorNz[-1] + dx])

        plt.show()

        return fig, ax
Esempio n. 25
0
def animate(ii):

    #for ii in range(1):
    removeFrame()
    # Grab current line and
    indx = np.where(lineID == ii)[0]

    srcLeft = []
    obs_l = []
    obs = []
    srcRight = []
    obs_r = []
    srcList = []
    # Split the obs file into left and right
    # Split the obs file into left and right
    for jj in range(len(indx)):

        # Grab corresponding data
        obs = np.hstack([obs, DCdobs2D.dobs[dataID == indx[jj]]])
        #std = dobs2D.std[dataID==indx[jj]]

        srcList.append(DCdobs2D.srcList[indx[jj]])

        Tx = DCdobs2D.srcList[indx[jj]].loc
        Rx = DCdobs2D.srcList[indx[jj]].rxList[0].locs

        # Create mid-point location
        Cmid = (Tx[0][0] + Tx[1][0]) / 2
        Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2

        ileft = Pmid < Cmid
        iright = Pmid >= Cmid

        temp = np.zeros(len(ileft))
        temp[ileft] = 1
        obs_l = np.hstack([obs_l, temp])

        temp = np.zeros(len(iright))
        temp[iright] = 1
        obs_r = np.hstack([obs_r, temp])

        if np.any(ileft):
            rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :])
            srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #std_l = np.hstack([std_l,std[ileft]])

        if np.any(iright):
            rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :])
            srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #obs_r = np.hstack([obs_r,iright])
            #std_r = np.hstack([std_r,std[iright]])

    DC2D_full = DC.SurveyDC(srcList)
    DC2D_full.dobs = np.asarray(obs)
    DC2D_full.std = DC2D_full.dobs * 0.
    DC2D_full.std[obs_l ==
                  1] = np.abs(DC2D_full.dobs[obs_l == 1]) * 0.02 + 2e-5
    DC2D_full.std[obs_r ==
                  1] = np.abs(DC2D_full.dobs[obs_r == 1]) * 0.06 + 4e-5

    #    DC2D_l = DC.SurveyDC(srcLeft)
    #    DC2D_l.dobs = np.asarray(obs[obs_l==1])
    #    DC2D_l.std = np.abs(np.asarray(DC2D_l.dobs))*0.05 + 2e-5
    #
    #    DC2D_r = DC.SurveyDC(srcRight)
    #    DC2D_r.dobs = np.asarray(obs[obs_r==1])
    #    DC2D_r.std = np.abs(np.asarray(DC2D_r.dobs))*0.05 + 2e-5

    survey = DC2D_full

    # Export data file
    DC.writeUBC_DCobs(inv_dir + dsep + obsfile2d, survey, '2D', 'SIMPLE')

    # Write input file
    fid = open(inv_dir + dsep + inp_file, 'w')
    fid.write('OBS LOC_X %s \n' % obsfile2d)
    fid.write('MESH FILE %s \n' % mshfile2d)
    fid.write('CHIFACT 1 \n')
    fid.write('TOPO DEFAULT \n')
    fid.write('INIT_MOD VALUE %e\n' % ini_mod)
    fid.write('REF_MOD VALUE %e\n' % ref_mod)
    fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1))
    fid.write('WEIGHT DEFAULT\n')
    fid.write('STORE_ALL_MODELS FALSE\n')
    fid.write('INVMODE CG\n')
    #fid.write('CG_PARAM 200 1e-4\n')
    fid.write('USE_MREF FALSE\n')
    #fid.write('BOUNDS VALUE 1e-4 1e+2\n')
    fid.close()

    os.chdir(inv_dir)
    os.system('dcinv2d ' + inp_file)

    #%% Load DC model and predicted data
    minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'dcinv2d.con')
    minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx))

    #%% Repeat for IP data
    indx = np.where(IPlineID == ii)[0]

    srcLeft = []
    obs_l = []
    std_l = []

    srcRight = []
    obs_r = []
    std_r = []

    obs_full = []
    std_full = []
    srcList = []

    # Split the obs file into left and right
    for jj in range(len(indx)):

        srcList.append(IPdobs2D.srcList[indx[jj]])
        # Grab corresponding data
        obs = IPdobs2D.dobs[IPdataID == indx[jj]]
        std = IPdobs2D.std[IPdataID == indx[jj]]

        obs_full = np.hstack([obs_full, obs])
        std_full = np.hstack([std_full, std])

        Tx = IPdobs2D.srcList[indx[jj]].loc
        Rx = IPdobs2D.srcList[indx[jj]].rxList[0].locs

        # Create mid-point location
        Cmid = (Tx[0][0] + Tx[1][0]) / 2
        Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2

        ileft = Pmid < Cmid
        iright = Pmid >= Cmid

        temp = np.zeros(len(ileft))
        temp[ileft] = 1
        obs_l = np.hstack([obs_l, temp])

        temp = np.zeros(len(iright))
        temp[iright] = 1
        obs_r = np.hstack([obs_r, temp])

        if np.any(ileft):
            rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :])
            srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #std_l = np.hstack([std_l,std[ileft]])

        if np.any(iright):
            rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :])
            srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

    IP2D_full = DC.SurveyDC(srcList)
    IP2D_full.dobs = np.asarray(obs_full)
    IP2D_full.std = np.asarray(std_full)

    IP2D_l = DC.SurveyDC(srcLeft)
    IP2D_l.dobs = np.asarray(obs_full[obs_l == 1])
    #IP2D_l.std = np.abs(np.asarray(obs_l))*0.03 + 2e-2

    IP2D_r = DC.SurveyDC(srcRight)
    IP2D_r.dobs = np.asarray(obs_full[obs_r == 1])
    #IP2D_r.std = np.abs(np.asarray(obs_r))*0.03 + 1e-2

    id_lbe = int(IPsurvey.srcList[indx[jj]].loc[0][1])

    mesh3d = Mesh.TensorMesh([hx, np.ones(1) * 100., hz],
                             x0=(-np.sum(padx) + np.min(srcMat[0][:, 0]),
                                 id_lbe - 50,
                                 np.max(srcMat[0][0, 2]) - np.sum(hz)))
    Mesh.TensorMesh.writeUBC(mesh3d,
                             home_dir + dsep + 'Mesh' + str(id_lbe) + '.msh')
    global ax1, ax2, ax3, ax5, ax6, fig

    ax2 = plt.subplot(3, 2, 2)
    ph = DC.plot_pseudoSection(IP2D_r,
                               ax2,
                               stype='pdp',
                               dtype='volt',
                               colorbar=False)
    ax2.set_title('Observed P-DP', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax2.set_xticklabels([])
    ax2.set_yticklabels([])

    ax1 = plt.subplot(3, 2, 1)
    DC.plot_pseudoSection(IP2D_l,
                          ax1,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax1.set_title('Observed DP-P', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax1.set_xticklabels([])
    z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5)
    z_label = np.linspace(20, 1, 5)
    ax1.set_yticks(map(int, z))
    ax1.set_yticklabels(map(str, map(int, z_label)), size=8)
    ax1.set_ylabel('n-spacing', fontsize=8)

    #%% Add labels
    bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1)
    ax2.text(0.00,
             1,
             'A',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1)
    ax2.text(0.1,
             1,
             'M',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1)
    ax2.text(0.2,
             1,
             'N',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1)
    ax1.text(0.00,
             1,
             'N',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1)
    ax1.text(0.1,
             1,
             'M',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1)
    ax1.text(0.2,
             1,
             'A',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    survey = IP2D_full

    # Export data file
    DC.writeUBC_DCobs(inv_dir + dsep + ipfile2d,
                      survey,
                      '2D',
                      'SIMPLE',
                      iptype=1)

    fid = open(inv_dir + dsep + inp_file, 'w')
    fid.write('OBS LOC_X %s \n' % ipfile2d)
    fid.write('MESH FILE %s \n' % mshfile2d)
    fid.write('CHIFACT 4 \n')
    fid.write('COND FILE dcinv2d.con\n')
    fid.write('TOPO DEFAULT \n')
    fid.write('INIT_MOD VALUE %e\n' % ini_mod)
    fid.write('REF_MOD VALUE 0.0\n')
    fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1))
    fid.write('WEIGHT DEFAULT\n')
    fid.write('STORE_ALL_MODELS FALSE\n')
    fid.write('INVMODE CG\n')
    #fid.write('CG_PARAM 200 1e-4\n')
    fid.write('USE_MREF FALSE\n')
    #fid.write('BOUNDS VALUE 1e-4 1e+2\n')
    fid.close()

    os.chdir(inv_dir)
    os.system('ipinv2d ' + inp_file)

    #%% Load model and predicted data
    minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'ipinv2d.chg')
    minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx))

    Mesh.TensorMesh.writeModelUBC(
        mesh3d, home_dir + dsep + 'Model' + str(id_lbe) + '.chg', minv.T)

    dpre = DC.readUBC_DC2Dpre(inv_dir + dsep + 'ipinv2d.pre')
    DCpre = dpre['DCsurvey']

    DCtemp = IP2D_l
    DCtemp.dobs = DCpre.dobs[obs_l == 1]

    ax5 = plt.subplot(3, 2, 3)
    DC.plot_pseudoSection(DCtemp,
                          ax5,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax5.set_title('Predicted', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax5.set_xticklabels([])
    z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5)
    z_label = np.linspace(20, 1, 5)
    ax5.set_yticks(map(int, z))
    ax5.set_yticklabels(map(str, map(int, z_label)), size=8)
    ax5.set_ylabel('n-spacing', fontsize=8)

    DCtemp = IP2D_r
    DCtemp.dobs = DCpre.dobs[obs_r == 1]

    ax6 = plt.subplot(3, 2, 4)
    DC.plot_pseudoSection(DCtemp,
                          ax6,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax6.set_title('Predicted', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax6.set_xticklabels([])
    ax6.set_yticklabels([])

    pos = ax6.get_position()
    cbarax = fig.add_axes([
        pos.x0 + 0.325, pos.y0 + 0.2, pos.width * 0.1, pos.height * 0.5
    ])  ## the parameters are the specified position you set
    cb = fig.colorbar(ph[0],
                      cax=cbarax,
                      orientation="vertical",
                      ax=ax6,
                      ticks=np.linspace(ph[0].get_clim()[0],
                                        ph[0].get_clim()[1], 4),
                      format="$10^{%.1f}$")
    cb.set_label("App. Charg.", size=8)

    ax3 = plt.subplot(3, 1, 3)
    ax3.set_title('2-D Model (S/m)', fontsize=10)
    ax3.set_xticks(map(int, x))
    ax3.set_xticklabels(map(str, map(int, x)))
    ax3.set_xlabel('Easting (m)', fontsize=8)
    ax3.set_yticks(map(int, z))
    ax3.set_yticklabels(map(str, map(int, z)), rotation='vertical')
    ax3.set_ylabel('Depth (m)', fontsize=8)

    plt.xlim([xmin, xmax])
    plt.ylim([zmin / 2, zmax])
    plt.gca().set_aspect('equal', adjustable='box')

    ph2 = plt.pcolormesh(mesh2d.vectorNx,
                         mesh2d.vectorNy, (minv),
                         vmin=vmin,
                         vmax=vmax)
    plt.gca().tick_params(axis='both', which='major', labelsize=8)

    plt.draw()

    for ss in range(survey.nSrc):
        Tx = survey.srcList[ss].loc[0]
        plt.scatter(Tx[0], mesh2d.vectorNy[-1] + 10, s=10)

    pos = ax3.get_position()
    ax3.set_position([pos.x0 + 0.025, pos.y0, pos.width, pos.height])
    pos = ax3.get_position()
    cbarax = fig.add_axes([
        pos.x0 + 0.65, pos.y0 + 0.01, pos.width * 0.05, pos.height * 0.75
    ])  ## the parameters are the specified position you set
    cb = fig.colorbar(ph2,
                      cax=cbarax,
                      orientation="vertical",
                      ax=ax3,
                      ticks=np.linspace(vmin, vmax, 4),
                      format="%4.1f")
    cb.set_label("Chargeability", size=8)

    pos = ax1.get_position()
    ax1.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height])

    pos = ax5.get_position()
    ax5.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height])

    pos = ax2.get_position()
    ax2.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height])

    pos = ax6.get_position()
    ax6.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height])

    #%% Add the extra

    bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="w", ec="k", lw=2)
    ax2.text(0.01, (float(ii) + 1.) / (len(uniqueID) + 2),
             'N: ' + str(id_lbe),
             transform=fig.transFigure,
             ha="left",
             va="center",
             size=8,
             bbox=bbox_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=2)
    ax2.text(0.01,
             0.9,
             'Line ID#',
             transform=fig.transFigure,
             ha="left",
             va="center",
             size=8,
             bbox=mrk_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="b", ec="k", lw=2)

    for jj in range(len(uniqueID)):
        ax2.text(0.1, (float(jj) + 1.) / (len(uniqueID) + 2),
                 ".",
                 transform=fig.transFigure,
                 ha="right",
                 va="center",
                 size=8,
                 bbox=mrk_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="r", ec="k", lw=2)

    ax2.text(0.1, (float(ii) + 1.) / (len(uniqueID) + 2),
             ".",
             transform=fig.transFigure,
             ha="right",
             va="center",
             size=8,
             bbox=mrk_props)
Esempio n. 26
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. 27
0
# if not gin:
#     print 'SimPED - Simulation has ended with return'
#     break
#==============================================================================

# Add z coordinate to all survey... assume flat
nz = mesh.vectorNz
var = np.c_[np.asarray(gin),np.ones(2).T*nz[-1]]

# Snap the endpoints to the grid. Easier to create 2D section.
indx = Utils.closestPoints(mesh, var )
endl = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*nz[-1]]
      
[Tx, Rx] = DC.gen_DCIPsurvey(endl, mesh, stype, a, b, n)
 
dl_len = np.sqrt( np.sum((endl[0,:] - endl[1,:])**2) ) 
dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len
dl_y = ( Tx[-1][1,1] - Tx[0][1,0]  ) / dl_len
azm =  np.arctan(dl_y/dl_x)
  
# Plot stations along line   
plt.scatter(Tx[0][0,:],Tx[0][1,:],s=20,c='g')
plt.scatter(Rx[0][:,0::3],Rx[0][:,1::3],s=20,c='y')

#%% Forward model data
data = []#np.zeros( nstn*nrx )
unct = []
problem = DC.ProblemDC_CC(mesh)
    
for ii in range(len(Tx)):
    start_time = time.time()