Exemplo n.º 1
0
    def MfRhoIDeriv(self, u, v, adjoint=False):
        """
            Derivative of :code:`MfRhoI` with respect to the model.
        """
        dMfRhoI_dI = -self.MfRhoI**2

        if self.storeInnerProduct:
            if adjoint:
                return (
                    self.MfRhoDerivMat.T * (
                        Utils.sdiag(u) * (dMfRhoI_dI.T * v)
                    )
                )
            else:
                return dMfRhoI_dI * (Utils.sdiag(u) * (self.MfRhoDerivMat*v))
        else:
            if self.storeJ:
                drho_dlogrho = Utils.sdiag(self.rho)*self.actMap.P
            else:
                drho_dlogrho = Utils.sdiag(self.rho)
            dMf_drho = self.mesh.getFaceInnerProductDeriv(self.rho)(u)
            if adjoint:
                return drho_dlogrho.T * (dMf_drho.T * (dMfRhoI_dI.T*v))
            else:
                return dMfRhoI_dI * (dMf_drho * (drho_dlogrho*v))
Exemplo n.º 2
0
 def MeSigmaDeriv(self, u, v, adjoint=False):
     """
     Derivative of MeSigma with respect to the model times a vector (u)
     """
     if self.storeInnerProduct:
         if adjoint:
             return self.MeSigmaDerivMat.T * (Utils.sdiag(u)*v)
         else:
             return Utils.sdiag(u)*(self.MeSigmaDerivMat * v)
     else:
         if self.storeJ:
             dsigma_dlogsigma = Utils.sdiag(self.sigma)*self.actMap.P
         else:
             dsigma_dlogsigma = Utils.sdiag(self.sigma)
         if adjoint:
             return (
                 dsigma_dlogsigma.T * (
                     self.mesh.getEdgeInnerProductDeriv(self.sigma)(u).T * v
                 )
             )
         else:
             return (
                 self.mesh.getEdgeInnerProductDeriv(self.sigma)(u) *
                 (dsigma_dlogsigma * v)
             )
Exemplo n.º 3
0
    def Wd(self):
        """getWd(survey)

            The data weighting matrix.

            The default is based on the norm of the data plus a noise floor.

            :rtype: scipy.sparse.csr_matrix
            :return: Wd

        """

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

            survey = self.survey

            if getattr(survey,'std', None) is None:
                print('SimPEG.DataMisfit.l2_DataMisfit assigning default std of 5%')
                survey.std = 0.05

            if getattr(survey, 'eps', None) is None:
                print('SimPEG.DataMisfit.l2_DataMisfit assigning default eps of 1e-5 * ||dobs||')
                survey.eps = np.linalg.norm(Utils.mkvc(survey.dobs),2)*1e-5

            self._Wd = Utils.sdiag(1/(abs(survey.dobs)*survey.std+survey.eps))
        return self._Wd
Exemplo n.º 4
0
    def getInterpolationMatCartMesh(self, Mrect, locType="CC", locTypeTo=None):
        """
            Takes a cartesian mesh and returns a projection to translate onto
            the cartesian grid.
        """

        assert self.isSymmetric, (
            "Currently we have not taken into account " "other projections for more complicated " "CylMeshes"
        )

        if locTypeTo is None:
            locTypeTo = locType

        if locType == "F":
            # do this three times for each component
            X = self.getInterpolationMatCartMesh(Mrect, locType="Fx", locTypeTo=locTypeTo + "x")
            Y = self.getInterpolationMatCartMesh(Mrect, locType="Fy", locTypeTo=locTypeTo + "y")
            Z = self.getInterpolationMatCartMesh(Mrect, locType="Fz", locTypeTo=locTypeTo + "z")
            return sp.vstack((X, Y, Z))
        if locType == "E":
            X = self.getInterpolationMatCartMesh(Mrect, locType="Ex", locTypeTo=locTypeTo + "x")
            Y = self.getInterpolationMatCartMesh(Mrect, locType="Ey", locTypeTo=locTypeTo + "y")
            Z = Utils.spzeros(getattr(Mrect, "n" + locTypeTo + "z"), self.nE)
            return sp.vstack((X, Y, Z))

        grid = getattr(Mrect, "grid" + locTypeTo)
        # This is unit circle stuff, 0 to 2*pi, starting at x-axis, rotating
        # counter clockwise in an x-y slice
        theta = -np.arctan2(grid[:, 0] - self.cartesianOrigin[0], grid[:, 1] - self.cartesianOrigin[1]) + np.pi / 2
        theta[theta < 0] += np.pi * 2.0
        r = ((grid[:, 0] - self.cartesianOrigin[0]) ** 2 + (grid[:, 1] - self.cartesianOrigin[1]) ** 2) ** 0.5

        if locType in ["CC", "N", "Fz", "Ez"]:
            G, proj = np.c_[r, theta, grid[:, 2]], np.ones(r.size)
        else:
            dotMe = {
                "Fx": Mrect.normals[: Mrect.nFx, :],
                "Fy": Mrect.normals[Mrect.nFx : (Mrect.nFx + Mrect.nFy), :],
                "Fz": Mrect.normals[-Mrect.nFz :, :],
                "Ex": Mrect.tangents[: Mrect.nEx, :],
                "Ey": Mrect.tangents[Mrect.nEx : (Mrect.nEx + Mrect.nEy), :],
                "Ez": Mrect.tangents[-Mrect.nEz :, :],
            }[locTypeTo]
            if "F" in locType:
                normals = np.c_[np.cos(theta), np.sin(theta), np.zeros(theta.size)]
                proj = (normals * dotMe).sum(axis=1)
            if "E" in locType:
                tangents = np.c_[-np.sin(theta), np.cos(theta), np.zeros(theta.size)]
                proj = (tangents * dotMe).sum(axis=1)
            G = np.c_[r, theta, grid[:, 2]]

        interpType = locType
        if interpType == "Fy":
            interpType = "Fx"
        elif interpType == "Ex":
            interpType = "Ey"

        Pc2r = self.getInterpolationMat(G, interpType)
        Proj = Utils.sdiag(proj)
        return Proj * Pc2r
Exemplo n.º 5
0
    def setUp(self):

        cs = 25.
        hx = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)]
        hy = [(cs,7, -1.3),(cs,21),(cs,7, 1.3)]
        hz = [(cs,7, -1.3),(cs,20)]
        mesh = Mesh.TensorMesh([hx, hy, hz],x0="CCN")
        sigma = np.ones(mesh.nC)*1e-2

        x = mesh.vectorCCx[(mesh.vectorCCx>-155.)&(mesh.vectorCCx<155.)]
        y = mesh.vectorCCx[(mesh.vectorCCy>-155.)&(mesh.vectorCCy<155.)]
        Aloc = np.r_[-200., 0., 0.]
        Bloc = np.r_[200., 0., 0.]
        M = Utils.ndgrid(x-25.,y, np.r_[0.])
        N = Utils.ndgrid(x+25.,y, np.r_[0.])
        phiA = EM.Analytics.DCAnalyticHalf(Aloc, [M,N], 1e-2, earth_type="halfspace")
        phiB = EM.Analytics.DCAnalyticHalf(Bloc, [M,N], 1e-2, earth_type="halfspace")
        data_anal = phiA-phiB

        rx = DC.Rx.Dipole(M, N)
        src = DC.Src.Dipole([rx], Aloc, Bloc)
        survey = DC.Survey([src])

        self.survey = survey
        self.mesh = mesh
        self.sigma = sigma
        self.data_anal = data_anal

        try:
            from pymatsolver import PardisoSolver
            self.Solver = PardisoSolver
        except ImportError:
            self.Solver = SolverLU
Exemplo n.º 6
0
        def test_regularizationMesh(self):

            for i, mesh in enumerate(self.meshlist):

                print('Testing {0:d}D'.format(mesh.dim))

                # mapping = r.mapPair(mesh)
                # reg = r(mesh, mapping=mapping)
                # m = np.random.rand(mapping.nP)

                if mesh.dim == 1:
                    indAct = Utils.mkvc(mesh.gridCC <= 0.8)
                elif mesh.dim == 2:
                    indAct = (
                        Utils.mkvc(
                            mesh.gridCC[:,-1] <=
                            2*np.sin(2*np.pi*mesh.gridCC[:, 0]) + 0.5
                        )
                    )
                elif mesh.dim == 3:
                    indAct = (
                        Utils.mkvc(
                            mesh.gridCC[:, -1] <=
                            2*np.sin(2*np.pi*mesh.gridCC[:, 0]) +
                            0.5 * 2*np.sin(2*np.pi*mesh.gridCC[:, 1]) + 0.5
                        )
                    )

                regmesh = Regularization.RegularizationMesh(
                    mesh, indActive=indAct
                )

                assert (regmesh.vol == mesh.vol[indAct]).all()
Exemplo n.º 7
0
    def meshs(self):
        if getattr(self, '_meshs', None) is None:
            csx, ncx, npadx = 50, 21, 12
            csy, ncy, npady = 50, 21, 12
            csz, ncz, npadz = 25, 40, 14
            pf = 1.5

            hx = Utils.meshTensor(
                [(csx, npadx, -pf), (csx, ncx), (csx, npadx, pf)]
            )
            hy = Utils.meshTensor(
                [(csy, npady, -pf), (csy, ncy), (csy, npady, pf)]
            )
            hz = Utils.meshTensor(
                [(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)]
            )

            x0 = np.r_[-hx.sum()/2., -hy.sum()/2., -hz[:npadz+ncz].sum()]
            self._meshs = Mesh.TensorMesh([hx, hy, hz], x0=x0)

            print('Secondary Mesh ... ')
            print(
                ' xmin, xmax, zmin, zmax: ', self._meshs.vectorCCx.min(),
                self._meshs.vectorCCx.max(), self._meshs.vectorCCy.min(),
                self._meshs.vectorCCy.max(), self._meshs.vectorCCz.min(),
                self._meshs.vectorCCz.max()
            )
            print(' nC, vnC', self._meshs.nC, self._meshs.vnC)

        return self._meshs
Exemplo n.º 8
0
    def __init__(self, rxList, freq, loc, orientation="Z", moment=1.0, mu=mu_0, **kwargs):
        self.freq = float(freq)
        self.loc = loc
        if isinstance(orientation, str):
            assert orientation.upper() in ["X", "Y", "Z"], (
                "orientation must " "be in 'X', 'Y', " "'Z' not {}".format(orientation)
            )
            orientation = orientationDict[orientation.upper()]
        elif (
            np.linalg.norm(orientation - np.r_[1.0, 0.0, 0.0]) > 1e-6
            or np.linalg.norm(orientation - np.r_[0.0, 1.0, 0.0]) > 1e-6
            or np.linalg.norm(orientation - np.r_[0.0, 0.0, 1.0]) > 1e-6
        ):
            warnings.warn(
                "Using orientations that are not in aligned with"
                " the mesh axes is not thoroughly tested. PR on "
                "a test??"
            )

        assert np.linalg.norm(orientation) == 1.0, "Orientation must have unit" " length, not {}".format(
            np.linalg.norm(orientation)
        )

        self.orientation = orientation
        self.moment = moment
        self.mu = mu
        Utils.setKwargs(self, **kwargs)
        BaseSrc.__init__(self, rxList)
Exemplo n.º 9
0
    def evalDeriv(self, f, freq, P0, df_dm_v=None, v=None, adjoint=False):

        if adjoint:

            if self.component == "real":
                PTvr = (P0.T*v).astype(complex)
                dZr_dfT_v = Utils.sdiag((1./(f**2)))*PTvr
                return dZr_dfT_v
            elif self.component == "imag":
                PTvi = P0.T*v*-1j
                dZi_dfT_v = Utils.sdiag((1./(f**2)))*PTvi
                return dZi_dfT_v
            elif self.component == "both":
                PTvr = (P0.T*np.r_[v[0]]).astype(complex)
                PTvi = P0.T*np.r_[v[1]]*-1j
                dZr_dfT_v = Utils.sdiag((1./(f**2)))*PTvr
                dZi_dfT_v = Utils.sdiag((1./(f**2)))*PTvi
                return dZr_dfT_v + dZi_dfT_v
            else:
                raise NotImplementedError('must be real, imag or both')

        else:

            dZd_dm_v = P0 * (Utils.sdiag(1./(f**2)) * df_dm_v)

            if self.component == "real":
                return dZd_dm_v.real
            elif self.component == "imag":
                return dZd_dm_v.imag
            elif self.component == "both":
                return np.r_[dZd_dm_v.real, dZd_dm_v.imag]
            else:
                raise NotImplementedError('must be real, imag or both')
Exemplo n.º 10
0
    def test_getInterpMatCartMesh_Edges2Faces(self):

        Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
        Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])

        Pe2f = Mc.getInterpolationMatCartMesh(Mr, 'E', locTypeTo='F')
        me = np.ones(Mc.nE)

        frect = Pe2f * me

        excc = Mr.aveFx2CC*Mr.r(frect, 'F', 'Fx')
        eycc = Mr.aveFy2CC*Mr.r(frect, 'F', 'Fy')
        ezcc = Mr.r(frect, 'F', 'Fz')

        indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(excc[indX]) - 0) < TOL
        assert np.abs(float(excc[indY]) + 1) < TOL
        assert np.abs(float(eycc[indX]) - 1) < TOL
        assert np.abs(float(eycc[indY]) - 0) < TOL
        assert np.abs(ezcc.sum()) < TOL

        mag = (excc**2 + eycc**2)**0.5
        dist = ((Mr.gridCC[:,0] + 0.2)**2  + (Mr.gridCC[:,1] + 0.2)**2)**0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Exemplo n.º 11
0
        def test_regularization_ActiveCells(self):
            for R in dir(Regularization):
                r = getattr(Regularization, R)
                if not inspect.isclass(r):
                    continue
                if not issubclass(r, Regularization.BaseRegularization):
                    continue

                for i, mesh in enumerate(self.meshlist):

                    print('Testing Active Cells {0:d}D'.format((mesh.dim)))

                    if mesh.dim == 1:
                        indActive = Utils.mkvc(mesh.gridCC <= 0.8)
                    elif mesh.dim == 2:
                        indActive = Utils.mkvc(mesh.gridCC[:,-1] <= 2*np.sin(2*np.pi*mesh.gridCC[:,0])+0.5)
                    elif mesh.dim == 3:
                        indActive = Utils.mkvc(mesh.gridCC[:,-1] <= 2*np.sin(2*np.pi*mesh.gridCC[:,0])+0.5 * 2*np.sin(2*np.pi*mesh.gridCC[:,1])+0.5)

                    for indAct in [indActive, indActive.nonzero()[0]]: # test both bool and integers
                        reg = r(mesh, indActive=indAct)
                        m = np.random.rand(mesh.nC)[indAct]
                        reg.mref = np.ones_like(m)*np.mean(m)

                    print('Check: phi_m (mref) = {0:f}'.format(reg.eval(reg.mref)))
                    passed = reg.eval(reg.mref) < TOL
                    self.assertTrue(passed)

                    print('Check:', R)
                    passed = Tests.checkDerivative(lambda m : [reg.eval(m), reg.evalDeriv(m)], m, plotIt=False)
                    self.assertTrue(passed)

                    print('Check 2 Deriv:', R)
                    passed = Tests.checkDerivative(lambda m : [reg.evalDeriv(m), reg.eval2Deriv(m)], m, plotIt=False)
                    self.assertTrue(passed)
Exemplo n.º 12
0
    def test_getInterpMatCartMesh_Faces2Edges(self):

        Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
        Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])

        Pf2e = Mc.getInterpolationMatCartMesh(Mr, 'F', locTypeTo='E')
        mf = np.ones(Mc.nF)

        ecart = Pf2e * mf

        excc = Mr.aveEx2CC*Mr.r(ecart, 'E', 'Ex')
        eycc = Mr.aveEy2CC*Mr.r(ecart, 'E', 'Ey')
        ezcc = Mr.r(ecart, 'E', 'Ez')

        indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(excc[indX]) - 1) < TOL
        assert np.abs(float(excc[indY]) - 0) < TOL
        assert np.abs(float(eycc[indX]) - 0) < TOL
        assert np.abs(float(eycc[indY]) - 1) < TOL
        assert np.abs((ezcc - 1).sum()) < TOL

        mag = (excc**2 + eycc**2)**0.5
        dist = ((Mr.gridCC[:,0] + 0.2)**2  + (Mr.gridCC[:,1] + 0.2)**2)**0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Exemplo n.º 13
0
    def test_getInterpMatCartMesh_Faces(self):

        Mr = Mesh.TensorMesh([100,100,2], x0='CC0')
        Mc = Mesh.CylMesh([np.ones(10)/5,1,10],x0='0C0',cartesianOrigin=[-0.2,-0.2,0])

        Pf = Mc.getInterpolationMatCartMesh(Mr, 'F')
        mf = np.ones(Mc.nF)

        frect = Pf * mf

        fxcc = Mr.aveFx2CC*Mr.r(frect, 'F', 'Fx')
        fycc = Mr.aveFy2CC*Mr.r(frect, 'F', 'Fy')
        fzcc = Mr.r(frect, 'F', 'Fz')

        indX = Utils.closestPoints(Mr, [0.45, -0.2, 0.5])
        indY = Utils.closestPoints(Mr, [-0.2, 0.45, 0.5])

        TOL = 1e-2
        assert np.abs(float(fxcc[indX]) - 1) < TOL
        assert np.abs(float(fxcc[indY]) - 0) < TOL
        assert np.abs(float(fycc[indX]) - 0) < TOL
        assert np.abs(float(fycc[indY]) - 1) < TOL
        assert np.abs((fzcc - 1).sum()) < TOL

        mag = (fxcc**2 + fycc**2)**0.5
        dist = ((Mr.gridCC[:,0] + 0.2)**2  + (Mr.gridCC[:,1] + 0.2)**2)**0.5

        assert np.abs(mag[dist > 0.1].max() - 1) < TOL
        assert np.abs(mag[dist > 0.1].min() - 1) < TOL
Exemplo n.º 14
0
    def setUp(self):

        cs = 12.5
        hx = [(cs, 7, -1.3), (cs, 61), (cs, 7, 1.3)]
        hy = [(cs, 7, -1.3), (cs, 20)]
        mesh = Mesh.TensorMesh([hx, hy], x0="CN")
        sighalf = 1e-2
        sigma = np.ones(mesh.nC)*sighalf
        x = np.linspace(0, 250., 20)
        M = Utils.ndgrid(x-12.5, np.r_[0.])
        N = Utils.ndgrid(x+12.5, np.r_[0.])
        A0loc = np.r_[-150, 0.]
        A1loc = np.r_[-125, 0.]
        rxloc = np.c_[M, np.zeros(20)]
        data_ana = EM.Analytics.DCAnalytic_Dipole_Pole(
                    [np.r_[A0loc, 0.], np.r_[A1loc, 0.]],
                    rxloc, sighalf, earth_type="halfspace")

        rx = DC.Rx.Pole_ky(M)
        src0 = DC.Src.Dipole([rx], A0loc, A1loc)
        survey = DC.Survey_ky([src0])

        self.survey = survey
        self.mesh = mesh
        self.sigma = sigma
        self.data_ana = data_ana
        self.plotIt = False

        try:
            from pymatsolver import PardisoSolver
            self.Solver = PardisoSolver
        except ImportError:
            self.Solver = SolverLU
Exemplo n.º 15
0
    def test_updateMultipliers(self):
        nP = 10

        m = np.random.rand(nP)

        W1 = Utils.sdiag(np.random.rand(nP))
        W2 = Utils.sdiag(np.random.rand(nP))

        phi1 = ObjectiveFunction.L2ObjectiveFunction(W=W1)
        phi2 = ObjectiveFunction.L2ObjectiveFunction(W=W2)

        phi = phi1 + phi2

        self.assertTrue(phi(m) == phi1(m) + phi2(m))

        phi.multipliers[0] = Utils.Zero()
        self.assertTrue(phi(m) == phi2(m))

        phi.multipliers[0] = 1.
        phi.multipliers[1] = Utils.Zero()

        self.assertTrue(len(phi.objfcts) == 2)
        self.assertTrue(len(phi.multipliers) == 2)
        self.assertTrue(len(phi) == 2)

        self.assertTrue(phi(m) == phi1(m))
Exemplo n.º 16
0
def drapeTopotoLoc(mesh, pts, actind=None, option="top", topo=None):
    """
        Drape location right below (cell center) the topography
    """
    if mesh.dim == 2:
        if pts.ndim > 1:
            raise Exception("pts should be 1d array")
    elif mesh.dim == 3:
        if pts.shape[1] == 3:
            raise Exception("shape of pts should be (x,3)")
    else:
        raise NotImplementedError()
    if actind is None:
        actind = Utils.surface2ind_topo(mesh, topo)
    if mesh._meshType == "TENSOR":
        meshtemp, topoCC = gettopoCC(mesh, actind, option=option)
        inds = Utils.closestPoints(meshtemp, pts)

    elif mesh._meshType == "TREE":
        if mesh.dim == 3:
            uniqXYlocs, topoCC = gettopoCC(mesh, actind, option=option)
            inds = closestPointsGrid(uniqXYlocs, pts)
        else:
            raise NotImplementedError()
    else:
        raise NotImplementedError()
    out = np.c_[pts, topoCC[inds]]
    return out
Exemplo n.º 17
0
    def forward(self, m, f=None):

        if f is None:
            f = self.fields(m)

        self.curModel = m
        Jv = self.dataPair(self.survey) #same size as the data
        # A = self.getA()
        JvAll = []
        for tind in range(len(self.survey.times)):
            #Pseudo-chareability
            t = self.survey.times[tind]
            v = self.DebyeTime(t)
            for src in self.survey.srcList:
                u_src = f[src, self._solutionType] # solution vector
                dA_dm_v = self.getADeriv(u_src, v)
                dRHS_dm_v = self.getRHSDeriv(src, v)
                du_dm_v = self.Ainv * ( - dA_dm_v + dRHS_dm_v )
                for rx in src.rxList:
                    timeindex = rx.getTimeP(self.survey.times)
                    if timeindex[tind]:
                        df_dmFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                        df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                        Jv[src, rx, t] = rx.evalDeriv(src, self.mesh, f, df_dm_v)

        # Conductivity (d u / d log sigma)
        if self._formulation is 'EB':
            return -Utils.mkvc(Jv)
        # Resistivity (d u / d log rho)
        if self._formulation is 'HJ':
            return Utils.mkvc(Jv)
Exemplo n.º 18
0
    def Jfull(self, m=None, f=None):
        if f is None:
            f = self.fields(m)

        nn = len(f)-1
        Asubs, Adiags, Bs = list(range(nn)), list(range(nn)), list(range(nn))
        for ii in range(nn):
            dt = self.timeSteps[ii]
            bc = self.getBoundaryConditions(ii, f[ii])
            Asubs[ii], Adiags[ii], Bs[ii] = self.diagsJacobian(
                m, f[ii], f[ii+1], dt, bc
            )
        Ad = sp.block_diag(Adiags)
        zRight = Utils.spzeros(
            (len(Asubs)-1)*Asubs[0].shape[0], Adiags[0].shape[1]
        )
        zTop = Utils.spzeros(
            Adiags[0].shape[0], len(Adiags)*Adiags[0].shape[1]
        )
        As = sp.vstack((zTop, sp.hstack((sp.block_diag(Asubs[1:]), zRight))))
        A = As + Ad
        B = np.array(sp.vstack(Bs).todense())

        Ainv = self.Solver(A, **self.solverOpts)
        AinvB = Ainv * B
        z = np.zeros((self.mesh.nC, B.shape[1]))
        du_dm = np.vstack((z, AinvB))
        J = self.survey.deriv(f, du_dm_v=du_dm)  # not multiplied by v
        return J
Exemplo n.º 19
0
    def Jvec(self, m, v, f=None):

        if f is None:
            f = self.fields(m)

        self.curModel = m

        Jv = self.dataPair(self.survey) #same size as the data

        A = self.getA()

        for src in self.survey.srcList:
            u_src = f[src, self._solutionType] # solution vector
            dA_dm_v = self.getADeriv(u_src, v)
            dRHS_dm_v = self.getRHSDeriv(src, v)
            du_dm_v = self.Ainv * ( - dA_dm_v + dRHS_dm_v )

            for rx in src.rxList:
                df_dmFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
        # Conductivity (d u / d log sigma)
        if self._formulation is 'EB':
            return -Utils.mkvc(Jv)
        # Conductivity (d u / d log rho)
        if self._formulation is 'HJ':
            return Utils.mkvc(Jv)
Exemplo n.º 20
0
    def setUp(self):

        cs = 25.
        hx = [(cs, 7, -1.3), (cs, 21), (cs, 7, 1.3)]
        hy = [(cs, 7, -1.3), (cs, 21), (cs, 7, 1.3)]
        hz = [(cs, 7, -1.3), (cs, 20), (cs, 7, -1.3)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCC")
        sigma = np.ones(mesh.nC)*1e-2

        x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)]
        y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)]

        Aloc = np.r_[-200., 0., 0.]
        Bloc = np.r_[200., 0., 0.]
        M = Utils.ndgrid(x-25., y, np.r_[0.])
        N = Utils.ndgrid(x+25., y, np.r_[0.])
        phiA = EM.Analytics.DCAnalytic_Pole_Dipole(
            Aloc, [M, N], 1e-2, earth_type="wholespace"
        )
        phiB = EM.Analytics.DCAnalytic_Pole_Dipole(
            Bloc, [M, N], 1e-2, earth_type="wholespace"
        )
        data_anal = phiA-phiB

        rx = DC.Rx.Dipole(M, N)
        src = DC.Src.Dipole([rx], Aloc, Bloc)
        survey = DC.Survey([src])

        self.survey = survey
        self.mesh = mesh
        self.sigma = sigma
        self.data_anal = data_anal
Exemplo n.º 21
0
    def Jtvec(self, m, v, f=None):
        if f is None:
            f = self.fields(m)

        self.model = m

        # Ensure v is a data object.
        if not isinstance(v, self.dataPair):
            v = self.dataPair(self.survey, v)

        Jtv = np.zeros(m.size)
        AT = self.getA()

        for src in self.survey.srcList:
            u_src = f[src, self._solutionType]
            for rx in src.rxList:
                PTv = rx.evalDeriv(src, self.mesh, f, v[src, rx], adjoint=True)  # wrt f, need possibility wrt m
                df_duTFun = getattr(f, '_{0!s}Deriv'.format(rx.projField), None)
                df_duT, df_dmT = df_duTFun(src, None, PTv, adjoint=True)
                ATinvdf_duT = self.Ainv * df_duT
                dA_dmT = self.getADeriv(u_src, ATinvdf_duT, adjoint=True)
                dRHS_dmT = self.getRHSDeriv(src, ATinvdf_duT, adjoint=True)
                du_dmT = -dA_dmT + dRHS_dmT
                Jtv += (df_dmT + du_dmT).astype(float)
        # Conductivity ((d u / d log sigma).T)
        if self._formulation == 'EB':
            return -Utils.mkvc(Jtv)
        # Conductivity ((d u / d log rho).T)
        if self._formulation == 'HJ':
            return Utils.mkvc(Jtv)
Exemplo n.º 22
0
    def setUp(self):

        cs = 12.5
        npad = 2
        hx = [(cs, npad, -1.3), (cs, 21), (cs, npad, 1.3)]
        hy = [(cs, npad, -1.3), (cs, 21), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, 20)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN")

        x = mesh.vectorCCx[(mesh.vectorCCx > -80.) & (mesh.vectorCCx < 80.)]
        y = mesh.vectorCCx[(mesh.vectorCCy > -80.) & (mesh.vectorCCy < 80.)]
        Aloc = np.r_[-100., 0., 0.]
        Bloc = np.r_[100., 0., 0.]
        M = Utils.ndgrid(x-12.5, y, np.r_[0.])
        N = Utils.ndgrid(x+12.5, y, np.r_[0.])
        radius = 50.
        xc = np.r_[0., 0., -100]
        blkind = Utils.ModelBuilder.getIndicesSphere(xc, radius, mesh.gridCC)
        sigmaInf = np.ones(mesh.nC)*1e-2
        eta = np.zeros(mesh.nC)
        eta[blkind] = 0.1
        sigma0 = sigmaInf*(1.-eta)

        rx = DC.Rx.Dipole(M, N)
        src = DC.Src.Dipole([rx], Aloc, Bloc)
        surveyDC = DC.Survey([src])

        self.surveyDC = surveyDC
        self.mesh = mesh
        self.sigmaInf = sigmaInf
        self.sigma0 = sigma0
        self.src = src
        self.eta = eta
Exemplo n.º 23
0
def run(plotIt=True):

    M = Mesh.TensorMesh([100, 100])
    h1 = Utils.meshTensor([(6, 7, -1.5), (6, 10), (6, 7, 1.5)])
    h1 = h1/h1.sum()
    M2 = Mesh.TensorMesh([h1, h1])
    V = Utils.ModelBuilder.randomModel(M.vnC, seed=79, its=50)
    v = Utils.mkvc(V)
    modh = Maps.Mesh2Mesh([M, M2])
    modH = Maps.Mesh2Mesh([M2, M])
    H = modH * v
    h = modh * H

    if not plotIt:
        return

    ax = plt.subplot(131)
    M.plotImage(v, ax=ax)
    ax.set_title('Fine Mesh (Original)')
    ax = plt.subplot(132)
    M2.plotImage(H, clim=[0, 1], ax=ax)
    ax.set_title('Course Mesh')
    ax = plt.subplot(133)
    M.plotImage(h, clim=[0, 1], ax=ax)
    ax.set_title('Fine Mesh (Interpolated)')
Exemplo n.º 24
0
    def test_ana_forward(self):

        survey = PF.BaseMag.BaseMagSurvey()

        Inc = 45.0
        Dec = 45.0
        Btot = 51000

        b0 = PF.MagAnalytics.IDTtoxyz(Inc, Dec, Btot)
        survey.setBackgroundField(Inc, Dec, Btot)
        xr = np.linspace(-300, 300, 41)
        yr = np.linspace(-300, 300, 41)
        X, Y = np.meshgrid(xr, yr)
        Z = np.ones((xr.size, yr.size)) * 150
        rxLoc = np.c_[Utils.mkvc(X), Utils.mkvc(Y), Utils.mkvc(Z)]
        survey.rxLoc = rxLoc

        self.prob.pair(survey)
        u = self.prob.fields(self.chi)
        B = u["B"]

        bxa, bya, bza = PF.MagAnalytics.MagSphereAnaFunA(
            rxLoc[:, 0], rxLoc[:, 1], rxLoc[:, 2], 100.0, 0.0, 0.0, 0.0, 0.01, b0, "secondary"
        )

        dpred = survey.projectFieldsAsVector(B)
        err = np.linalg.norm(dpred - np.r_[bxa, bya, bza]) / np.linalg.norm(np.r_[bxa, bya, bza])
        self.assertTrue(err < 0.08)
Exemplo n.º 25
0
 def set_ij_height(self):
     """
     Compute (I, J) indicies to form sparse sensitivity matrix
     This will be used in GlobalEM1DProblem when after sensitivity matrix
     for each sounding is computed
     """
     I = []
     J = []
     shift_for_J = 0
     shift_for_I = 0
     m = self.n_layer
     for i in range(n_sounding):
         n = self.nD_vec[i]
         J_temp = np.tile(np.arange(m), (n, 1)) + shift_for_J
         I_temp = (
             np.tile(np.arange(n), (1, m)).reshape((n, m), order='F') +
             shift_for_I
         )
         J.append(Utils.mkvc(J_temp))
         I.append(Utils.mkvc(I_temp))
         shift_for_J += m
         shift_for_I = I_temp[-1, -1] + 1
     J = np.hstack(J).astype(int)
     I = np.hstack(I).astype(int)
     return (I, J)
Exemplo n.º 26
0
    def setUp(self):

        cs = 25.
        hx = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hy = [(cs, 0, -1.3), (cs, 21), (cs, 0, 1.3)]
        hz = [(cs, 0, -1.3), (cs, 20)]
        mesh = Mesh.TensorMesh([hx, hy, hz], x0="CCN")
        blkind0 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[-100., -100., -200.], 75., mesh.gridCC
        )
        blkind1 = Utils.ModelBuilder.getIndicesSphere(
            np.r_[100., 100., -200.], 75., mesh.gridCC
        )
        sigma = np.ones(mesh.nC)*1e-2
        eta = np.zeros(mesh.nC)
        tau = np.ones_like(sigma)*1.
        eta[blkind0] = 0.1
        eta[blkind1] = 0.1
        tau[blkind0] = 0.1
        tau[blkind1] = 0.01

        x = mesh.vectorCCx[(mesh.vectorCCx > -155.) & (mesh.vectorCCx < 155.)]
        y = mesh.vectorCCx[(mesh.vectorCCy > -155.) & (mesh.vectorCCy < 155.)]
        Aloc = np.r_[-200., 0., 0.]
        Bloc = np.r_[200., 0., 0.]
        M = Utils.ndgrid(x-25., y, np.r_[0.])
        N = Utils.ndgrid(x+25., y, np.r_[0.])

        times = np.arange(10)*1e-3 + 1e-3
        rx = SIP.Rx.Dipole(M, N, times)
        src = SIP.Src.Dipole([rx], Aloc, Bloc)
        survey = SIP.Survey([src])
        wires = Maps.Wires(('eta', mesh.nC), ('taui', mesh.nC))
        problem = SIP.Problem3D_N(
            mesh,
            sigma=sigma,
            etaMap=wires.eta,
            tauiMap=wires.taui
        )
        problem.Solver = Solver
        problem.pair(survey)
        mSynth = np.r_[eta, 1./tau]
        survey.makeSyntheticData(mSynth)
        # Now set up the problem to do some minimization
        dmis = DataMisfit.l2_DataMisfit(survey)
        reg = Regularization.Tikhonov(mesh)
        opt = Optimization.InexactGaussNewton(
            maxIterLS=20, maxIter=10, tolF=1e-6,
            tolX=1e-6, tolG=1e-6, maxIterCG=6
        )
        invProb = InvProblem.BaseInvProblem(dmis, reg, opt, beta=1e4)
        inv = Inversion.BaseInversion(invProb)

        self.inv = inv
        self.reg = reg
        self.p = problem
        self.mesh = mesh
        self.m0 = mSynth
        self.survey = survey
        self.dmis = dmis
Exemplo n.º 27
0
    def setUp(self):

        cs = 12.5
        hx = [(cs,7, -1.3),(cs,61),(cs,7, 1.3)]
        hy = [(cs,7, -1.3),(cs,20)]
        mesh = Mesh.TensorMesh([hx, hy],x0="CN")
        sighalf = 1e-2
        sigma = np.ones(mesh.nC)*sighalf
        x = np.linspace(-135, 250., 20)
        M = Utils.ndgrid(x-12.5, np.r_[0.])
        N = Utils.ndgrid(x+12.5, np.r_[0.])
        A0loc = np.r_[-150, 0.]
        A1loc = np.r_[-130, 0.]
        rxloc = [np.c_[M, np.zeros(20)], np.c_[N, np.zeros(20)]]
        data_anal = EM.Analytics.DCAnalyticHalf(np.r_[A0loc, 0.], rxloc, sighalf, earth_type="halfspace")

        rx = DC.Rx.Dipole_ky(M, N)
        src0 = DC.Src.Pole([rx], A0loc)
        survey = DC.Survey_ky([src0])

        self.survey = survey
        self.mesh = mesh
        self.sigma = sigma
        self.data_anal = data_anal

        try:
            from pymatsolver import MumpsSolver
            self.Solver = MumpsSolver
        except ImportError, e:
            self.Solver = SolverLU
Exemplo n.º 28
0
    def __init__(self, h_in, x0_in=None):
        assert type(h_in) in [list, tuple], 'h_in must be a list'
        assert len(h_in) in [1,2,3], 'h_in must be of dimension 1, 2, or 3'
        h = range(len(h_in))
        for i, h_i in enumerate(h_in):
            if Utils.isScalar(h_i) and type(h_i) is not np.ndarray:
                # This gives you something over the unit cube.
                h_i = self._unitDimensions[i] * np.ones(int(h_i))/int(h_i)
            elif type(h_i) is list:
                h_i = Utils.meshTensor(h_i)
            assert isinstance(h_i, np.ndarray), ("h[%i] is not a numpy array." % i)
            assert len(h_i.shape) == 1, ("h[%i] must be a 1D numpy array." % i)
            h[i] = h_i[:] # make a copy.

        x0 = np.zeros(len(h))
        if x0_in is not None:
            assert len(h) == len(x0_in), "Dimension mismatch. x0 != len(h)"
            for i in range(len(h)):
                x_i, h_i = x0_in[i], h[i]
                if Utils.isScalar(x_i):
                    x0[i] = x_i
                elif x_i == '0':
                    x0[i] = 0.0
                elif x_i == 'C':
                    x0[i] = -h_i.sum()*0.5
                elif x_i == 'N':
                    x0[i] = -h_i.sum()
                else:
                    raise Exception("x0[%i] must be a scalar or '0' to be zero, 'C' to center, or 'N' to be negative." % i)

        BaseRectangularMesh.__init__(self, np.array([x.size for x in h]), x0)

        # Ensure h contains 1D vectors
        self._h = [Utils.mkvc(x.astype(float)) for x in h]
Exemplo n.º 29
0
 def MnSigmaDeriv(self, u):
     """
         Derivative of MnSigma with respect to the model
     """
     sigma = self.curModel.sigma
     sigmaderiv = self.curModel.sigmaDeriv
     vol = self.mesh.vol
     return Utils.sdiag(u)*self.mesh.aveN2CC.T*Utils.sdiag(vol) * self.curModel.sigmaDeriv
Exemplo n.º 30
0
    def diagsJacobian(self, m, hn, hn1, dt, bc):
        """Diagonals and rhs of the jacobian system

        The matrix that we are computing has the form::

            .-                                      -. .-  -.   .-  -.
            |  Adiag                                 | | h1 |   | b1 |
            |   Asub    Adiag                        | | h2 |   | b2 |
            |            Asub    Adiag               | | h3 | = | b3 |
            |                 ...     ...            | | .. |   | .. |
            |                         Asub    Adiag  | | hn |   | bn |
            '-                                      -' '-  -'   '-  -'
        """
        if m is not None:
            self.model = m

        DIV = self.mesh.faceDiv
        GRAD = self.mesh.cellGrad
        BC = self.mesh.cellGradBC
        AV = self.mesh.aveF2CC.T
        Dz = self.Dz

        dT = self.water_retention.derivU(hn)
        dT1 = self.water_retention.derivU(hn1)
        dTm = self.water_retention.derivM(hn)
        dTm1 = self.water_retention.derivM(hn1)

        K1 = self.hydraulic_conductivity(hn1)
        dK1 = self.hydraulic_conductivity.derivU(hn1)
        dKm1 = self.hydraulic_conductivity.derivM(hn1)

        # Compute part of the derivative of:
        #
        #       DIV*diag(GRAD*hn1+BC*bc)*(AV*(1.0/K))^-1

        DdiagGh1 = DIV*Utils.sdiag(GRAD*hn1+BC*bc)
        diagAVk2_AVdiagK2 = (
            Utils.sdiag((AV*(1./K1))**(-2)) *
            AV*Utils.sdiag(K1**(-2))
        )

        Asub = (-1.0/dt)*dT

        Adiag = (
            (1.0/dt)*dT1 -
            DdiagGh1*diagAVk2_AVdiagK2*dK1 -
            DIV*Utils.sdiag(1./(AV*(1./K1)))*GRAD -
            Dz*diagAVk2_AVdiagK2*dK1
        )

        B = (
            DdiagGh1*diagAVk2_AVdiagK2*dKm1 +
            Dz*diagAVk2_AVdiagK2*dKm1 +
            (1.0/dt)*(dTm - dTm1)
        )

        return Asub, Adiag, B
Exemplo n.º 31
0
    def get_interpolation_matrix(
        self,
        npts=20,
        epsilon=None
    ):

        tree_2d = kdtree(self.topography[:, :2])
        xy = Utils.ndgrid(self.mesh_3d.vectorCCx, self.mesh_3d.vectorCCy)

        distance, inds = tree_2d.query(xy, k=npts)
        if epsilon is None:
            epsilon = np.min([self.mesh_3d.hx.min(), self.mesh_3d.hy.min()])

        w = 1. / (distance + epsilon)**2
        w = Utils.sdiag(1./np.sum(w, axis=1)) * (w)
        I = Utils.mkvc(
            np.arange(inds.shape[0]).reshape([-1, 1]).repeat(npts, axis=1)
        )
        J = Utils.mkvc(inds)

        self._P = sp.coo_matrix(
            (Utils.mkvc(w), (I, J)),
            shape=(inds.shape[0], self.topography.shape[0])
        )

        mesh_1d = Mesh.TensorMesh([np.r_[self.hz[:-1], 1e20]])

        z = self.P*self.topography[:, 2]

        self._actinds = Utils.surface2ind_topo(self.mesh_3d, np.c_[xy, z])

        Z = np.empty(self.mesh_3d.vnC, dtype=float, order='F')
        Z = self.mesh_3d.gridCC[:, 2].reshape(
            (self.mesh_3d.nCx*self.mesh_3d.nCy, self.mesh_3d.nCz), order='F'
        )
        ACTIND = self._actinds.reshape(
            (self.mesh_3d.nCx*self.mesh_3d.nCy, self.mesh_3d.nCz), order='F'
        )

        self._Pz = []

        # This part can be cythonized or parallelized
        for i_xy in range(self.mesh_3d.nCx*self.mesh_3d.nCy):
            actind_temp = ACTIND[i_xy, :]
            z_temp = -(Z[i_xy, :] - z[i_xy])
            self._Pz.append(mesh_1d.getInterpolationMat(z_temp[actind_temp]))
Exemplo n.º 32
0
        def switchKernal(xx):
            """Switches over the different options."""
            if xType in ['CC', 'N']:
                nn = (self._n) if xType == 'CC' else (self._n + 1)
                assert xx.size == np.prod(
                    nn), "Number of elements must not change."
                return outKernal(xx, nn)
            elif xType in ['F', 'E']:
                # This will only deal with components of fields, not full 'F' or 'E'
                xx = Utils.mkvc(xx)  # unwrap it in case it is a matrix
                nn = self.vnF if xType == 'F' else self.vnE
                nn = np.r_[0, nn]

                nx = [0, 0, 0]
                nx[0] = self.vnFx if xType == 'F' else self.vnEx
                nx[1] = self.vnFy if xType == 'F' else self.vnEy
                nx[2] = self.vnFz if xType == 'F' else self.vnEz

                for dim, dimName in enumerate(['x', 'y', 'z']):
                    if dimName in outType:
                        assert self.dim > dim, (
                            "Dimensions of mesh not great enough for %s%s",
                            (xType, dimName))
                        assert xx.size == np.sum(
                            nn), 'Vector is not the right size.'
                        start = np.sum(nn[:dim + 1])
                        end = np.sum(nn[:dim + 2])
                        return outKernal(xx[start:end], nx[dim])
            elif xTypeIsFExyz:
                # This will deal with partial components (x, y or z) lying on edges or faces
                if 'x' in xType:
                    nn = self.vnFx if 'F' in xType else self.vnEx
                elif 'y' in xType:
                    nn = self.vnFy if 'F' in xType else self.vnEy
                elif 'z' in xType:
                    nn = self.vnFz if 'F' in xType else self.vnEz
                assert xx.size == np.prod(nn), 'Vector is not the right size.'
                return outKernal(xx, nn)
Exemplo n.º 33
0
    def ePrimaryDeriv(self, prob, v, adjoint=False, f=None):

        if f is None:
            f = self._primaryFields(prob)

        # if adjoint is True:
        #     raise NotImplementedError
        if self.primaryProblem._formulation == 'EB':
            if adjoint is True:
                epDeriv = self._primaryFieldsDeriv(
                    prob, (self._ProjPrimary(prob, 'E', 'E').T * v),
                    f=f,
                    adjoint=adjoint)
            else:
                epDeriv = (self._ProjPrimary(prob, 'E', 'E') *
                           self._primaryFieldsDeriv(prob, v, f=f))
        elif self.primaryProblem._formulation == 'HJ':
            if adjoint is True:
                PTv = (self.primaryProblem.MfI.T *
                       (self._ProjPrimary(prob, 'F', 'E').T * v))
                epDeriv = (
                    self.primaryProblem.MfRhoDeriv(f[:, 'j']).T * PTv +
                    self._primaryFieldsDeriv(prob,
                                             self.primaryProblem.MfRho.T * PTv,
                                             adjoint=adjoint,
                                             f=f))
                # epDeriv =(

                #     (self.primaryProblem.MfI.T * PTv)
                #     )
            else:
                epDeriv = (self._ProjPrimary(prob, 'F', 'E') *
                           (self.primaryProblem.MfI *
                            ((self.primaryProblem.MfRhoDeriv(f[:, 'j']) * v) +
                             (self.primaryProblem.MfRho *
                              self._primaryFieldsDeriv(prob, v, f=f)))))

        return Utils.mkvc(epDeriv)
Exemplo n.º 34
0
    def bPrimary(self, prob):
        """
        The primary magnetic flux density from the analytic solution for
        magnetic fields from a dipole

        :param BaseFDEMProblem prob: FDEM problem
        :rtype: numpy.ndarray
        :return: primary magnetic field
        """

        formulation = prob._formulation

        if formulation is 'EB':
            gridX = prob.mesh.gridFx
            gridY = prob.mesh.gridFy
            gridZ = prob.mesh.gridFz

        elif formulation is 'HJ':
            gridX = prob.mesh.gridEx
            gridY = prob.mesh.gridEy
            gridZ = prob.mesh.gridEz

        srcfct = MagneticDipoleFields
        if prob.mesh._meshType is 'CYL':
            if not prob.mesh.isSymmetric:
                # TODO ?
                raise NotImplementedError(
                    'Non-symmetric cyl mesh not implemented yet!')
            bx = srcfct(self.loc, gridX, 'x', mu=self.mu, moment=self.moment)
            bz = srcfct(self.loc, gridZ, 'z', mu=self.mu, moment=self.moment)
            b = np.concatenate((bx, bz))
        else:
            bx = srcfct(self.loc, gridX, 'x', mu=self.mu, moment=self.moment)
            by = srcfct(self.loc, gridY, 'y', mu=self.mu, moment=self.moment)
            bz = srcfct(self.loc, gridZ, 'z', mu=self.mu, moment=self.moment)
            b = np.concatenate((bx, by, bz))

        return Utils.mkvc(b)
Exemplo n.º 35
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
Exemplo n.º 36
0
    def setUp(self):
        M = Mesh.TensorMesh([np.ones(8), np.ones(30)])

        M.setCellGradBC(['neumann', 'dirichlet'])

        params = Richards.Empirical.HaverkampParams().celia1990
        params['Ks'] = np.log(params['Ks'])
        E = Richards.Empirical.Haverkamp(M, **params)

        bc = np.array([-61.5, -20.7])
        bc = np.r_[np.zeros(M.nCy * 2),
                   np.ones(M.nCx) * bc[0],
                   np.ones(M.nCx) * bc[1]]
        h = np.zeros(M.nC) + bc[0]
        prob = Richards.RichardsProblem(M,
                                        E,
                                        timeSteps=[(40, 3), (60, 3)],
                                        boundaryConditions=bc,
                                        initialConditions=h,
                                        doNewton=False,
                                        method='mixed',
                                        tolRootFinder=1e-6,
                                        debug=False)
        prob.Solver = Solver

        locs = Utils.ndgrid(np.array([5, 7.]), np.array([5, 15, 25.]))
        times = prob.times[3:5]
        rxSat = Richards.RichardsRx(locs, times, 'saturation')
        rxPre = Richards.RichardsRx(locs, times, 'pressureHead')
        survey = Richards.RichardsSurvey([rxSat, rxPre])

        prob.pair(survey)

        self.h0 = h
        self.M = M
        self.Ks = params['Ks']
        self.prob = prob
        self.survey = survey
Exemplo n.º 37
0
    def setUp(self):
        print('\nTesting Transect for analytic')

        cs = 10.
        ncx, ncy, ncz = 10, 10, 10
        npad = 5
        freq = 1e2

        hx = [(cs, npad, -1.3), (cs, ncx), (cs, npad, 1.3)]
        hy = [(cs, npad, -1.3), (cs, ncy), (cs, npad, 1.3)]
        hz = [(cs, npad, -1.3), (cs, ncz), (cs, npad, 1.3)]
        mesh = Mesh.TensorMesh([hx, hy, hz], 'CCC')

        mapping = Maps.ExpMap(mesh)

        x = np.linspace(-10, 10, 5)
        XYZ = Utils.ndgrid(x, np.r_[0], np.r_[0])
        rxList = EM.FDEM.Rx.Point_e(XYZ, orientation='x', component='imag')
        SrcList = [
            EM.FDEM.Src.MagDipole([rxList], loc=np.r_[0., 0., 0.], freq=freq),
            EM.FDEM.Src.CircularLoop([rxList],
                                     loc=np.r_[0., 0., 0.],
                                     freq=freq,
                                     radius=np.sqrt(1. / np.pi)),
            # EM.FDEM.Src.MagDipole_Bfield([rxList], loc=np.r_[0., 0., 0.],
            #                              freq=freq), # less accurate
        ]

        survey = EM.FDEM.Survey(SrcList)

        prb = EM.FDEM.Problem3D_b(mesh, mapping=mapping)
        prb.pair(survey)

        try:
            from pymatsolver import MumpsSolver
            prb.Solver = MumpsSolver
        except ImportError, e:
            prb.Solver = SolverLU
Exemplo n.º 38
0
    def test_2sum(self):
        nP = 80
        alpha1 = 100
        alpha2 = 200

        phi1 = (ObjectiveFunction.L2ObjectiveFunction(
            W=Utils.sdiag(np.random.rand(nP))) +
                alpha1 * ObjectiveFunction.L2ObjectiveFunction())
        phi2 = ObjectiveFunction.L2ObjectiveFunction() + alpha2 * phi1
        self.assertTrue(phi2.test(eps=EPS))

        self.assertTrue(len(phi1.multipliers) == 2)
        self.assertTrue(len(phi2.multipliers) == 2)

        self.assertTrue(len(phi1.objfcts) == 2)
        self.assertTrue(len(phi2.objfcts) == 2)
        self.assertTrue(len(phi2) == 2)

        self.assertTrue(len(phi1) == 2)
        self.assertTrue(len(phi2) == 2)

        self.assertTrue(np.all(phi1.multipliers == np.r_[1., alpha1]))
        self.assertTrue(np.all(phi2.multipliers == np.r_[1., alpha2]))
Exemplo n.º 39
0
def B_field_from_SheetCurruent(XYZ, srcLoc, sig, f, E0=1., orientation='X', kappa=0., epsr=1., t=0.):
    """
        Plane wave propagating downward (negative z (depth))
    """

    XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & f.shape[0] > 1:
        raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")

    mu = mu_0*(1+kappa)
    epsilon = epsilon_0*epsr
    sig_hat = sig + 1j*omega(f)*epsilon
    k  = np.sqrt( omega(f)**2. *mu*epsilon -1j*omega(f)*mu*sig )
    Z = omega(f)*mu/k
    if orientation == "X":
        z = XYZ[:,2]
        Bx = mu*np.zeros_like(z)
        By = mu*E0/Z*np.exp(1j*(k*(z-srcLoc)+omega(f)*t))
        Bz = mu*np.zeros_like(z)
        return Bx, By, Bz
    else:
        raise NotImplementedError()
Exemplo n.º 40
0
    def isInside(self, pts, locType='N'):
        """
        Determines if a set of points are inside a mesh.

        :param numpy.ndarray pts: Location of points to test
        :rtype numpy.ndarray
        :return inside, numpy array of booleans
        """
        pts = Utils.asArray_N_x_Dim(pts, self.dim)

        tensors = self.getTensor(locType)

        if locType == 'N' and self._meshType == 'CYL':
            #NOTE: for a CYL mesh we add a node to check if we are inside in the radial direction!
            tensors[0] = np.r_[0., tensors[0]]
            tensors[1] = np.r_[tensors[1], 2.0 * np.pi]

        inside = np.ones(pts.shape[0], dtype=bool)
        for i, tensor in enumerate(tensors):
            TOL = np.diff(tensor).min() * 1.0e-10
            inside = inside & (pts[:, i] >= tensor.min() - TOL) & (
                pts[:, i] <= tensor.max() + TOL)
        return inside
Exemplo n.º 41
0
    def activeCells(self):
        if getattr(self, '_activeCells', None) is None:
            if getattr(self, 'topofile', None) is not None:
                topo = np.genfromtxt(self.basePath + self.topofile, skip_header=1)
                # Find the active cells
                active = Utils.surface2ind_topo(self.mesh, topo, 'N')

            elif isinstance(self._staticInput, float):
                active = self.m0 != self._staticInput

            else:
                # Read from file active cells with 0:air, 1:dynamic, -1 static
                active = self.activeModel != 0

            inds = np.asarray([inds for inds, elem in enumerate(active, 1)
                              if elem], dtype=int) - 1
            self._activeCells = inds

            # Reduce m0 to active space
            if len(self.m0) > len(self._activeCells):
                self._m0 = self.m0[self._activeCells]

        return self._activeCells
Exemplo n.º 42
0
    def fields(self, m):
        """
            Return magnetic potential (u) and flux (B)
            u: defined on the cell center [nC x 1]
            B: defined on the cell center [nF x 1]

            After we compute u, then we update B.

            .. math ::

                \mathbf{B}_s = (\MfMui)^{-1}\mathbf{M}^f_{\mu_0^{-1}}\mathbf{B}_0-\mathbf{B}_0 -(\MfMui)^{-1}\Div^T \mathbf{u}

        """
        self.makeMassMatrices(m)
        A = self.getA(m)
        rhs = self.getRHS(m)
        m1 = sp.linalg.interface.aslinearoperator(Utils.sdiag(1 /
                                                              A.diagonal()))
        u, info = sp.linalg.bicgstab(A, rhs, tol=1e-6, maxiter=1000, M=m1)
        B0 = self.getB0()
        B = self.MfMuI * self.MfMu0 * B0 - B0 - self.MfMuI * self._Div.T * u

        return {'B': B, 'u': u}
Exemplo n.º 43
0
def writeVectorUBC(mesh, fileName, model):
    """
        Writes a vector model associated with a SimPEG TensorMesh
        to a UBC-GIF format model file.

        :param string fileName: File to write to
        :param numpy.ndarray model: The model
    """

    modelMatTR = np.zeros_like(model)

    for ii in range(3):
        # Reshape model to a matrix
        modelMat = mesh.r(model[:, ii], "CC", "CC", "M")
        # Transpose the axes
        modelMatT = modelMat.transpose((2, 0, 1))
        # Flip UBC order
        modelMatTR[:, ii] = Utils.mkvc(modelMatT[::-1, :, :])

        # Flip z to positive down for MeshTools3D
        if ii == 2:
            modelMatTR[:, ii] *= -1
    np.savetxt(fileName, modelMatTR)
Exemplo n.º 44
0
    def getInitialFieldsDeriv(self, src, v, adjoint=False, f=None):

        ifieldsDeriv = Utils.mkvc(
            getattr(
                src, '{}InitialDeriv'.format(self._fieldType), None
            )(self, v, adjoint, f)
        )

        # take care of any utils.zero cases
        if adjoint is False:
            if self._fieldType in ['b', 'j']:
                ifieldsDeriv += np.zeros(self.mesh.nF)
            elif self._fieldType in ['e', 'h']:
                ifieldsDeriv += np.zeros(self.mesh.nE)

        elif adjoint is True:
            if self._fieldType in ['b', 'j']:
                ifieldsDeriv += np.zeros(self.mesh.nF)
            elif self._fieldType in ['e', 'h']:
                ifieldsDeriv[0] += np.zeros(self.mesh.nE)
            ifieldsDeriv[1] += np.zeros_like(self.model) # take care of a Utils.Zero() case

        return ifieldsDeriv
Exemplo n.º 45
0
def run(plotIt=True):
    M = Mesh.TensorMesh([32, 32])
    v = Utils.ModelBuilder.randomModel(M.vnC, seed=789)
    v = Utils.mkvc(v)

    O = Mesh.TreeMesh([32, 32])
    O.refine(1)

    def function(cell):
        if (cell.center[0] < 0.75 and cell.center[0] > 0.25
                and cell.center[1] < 0.75 and cell.center[1] > 0.25):
            return 5
        if (cell.center[0] < 0.9 and cell.center[0] > 0.1
                and cell.center[1] < 0.9 and cell.center[1] > 0.1):
            return 4
        return 3

    O.refine(function)

    P = M.getInterpolationMat(O.gridCC, 'CC')

    ov = P * v

    if not plotIt:
        return

    fig, axes = plt.subplots(1, 2, figsize=(10, 5))

    out = M.plotImage(v, grid=True, ax=axes[0])
    cb = plt.colorbar(out[0], ax=axes[0])
    cb.set_label("Random Field")
    axes[0].set_title('TensorMesh')

    out = O.plotImage(ov, grid=True, ax=axes[1], clim=[0, 1])
    cb = plt.colorbar(out[0], ax=axes[1])
    cb.set_label("Random Field")
    axes[1].set_title('TreeMesh')
Exemplo n.º 46
0
def ElectricDipoleWholeSpace(XYZ, srcLoc, sig, f, current=1., length=1., orientation='X', mu=mu_0):
    XYZ = Utils.asArray_N_x_Dim(XYZ, 3)

    dx = XYZ[:,0]-srcLoc[0]
    dy = XYZ[:,1]-srcLoc[1]
    dz = XYZ[:,2]-srcLoc[2]

    r  = np.sqrt( dx**2. + dy**2. + dz**2.)
    k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    kr = k*r

    front = current * length / (4. * np.pi * sig * r**3) * np.exp(-1j*k*r)
    mid   = -k**2 * r**2 + 3*1j*k*r + 3

    # Ex = front*((dx**2 / r**2)*mid + (k**2 * r**2 -1j*k*r))
    # Ey = front*(dx*dy  / r**2)*mid
    # Ez = front*(dx*dz  / r**2)*mid

    if orientation.upper() == 'X':
        Ex = front*((dx**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
        Ey = front*(dx*dy  / r**2)*mid
        Ez = front*(dx*dz  / r**2)*mid
        return Ex, Ey, Ez

    elif orientation.upper() == 'Y':
        #  x--> y, y--> z, z-->x
        Ey = front*((dy**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
        Ez = front*(dy*dz  / r**2)*mid
        Ex = front*(dy*dx  / r**2)*mid
        return Ex, Ey, Ez

    elif orientation.upper() == 'Z':
        # x --> z, y --> x, z --> y
        Ez = front*((dz**2 / r**2)*mid + (k**2 * r**2 -1j*k*r-1.))
        Ex = front*(dz*dx  / r**2)*mid
        Ey = front*(dz*dy  / r**2)*mid
        return Ex, Ey, Ez
Exemplo n.º 47
0
    def Jvec(self, m, v, f=None):
        """
        Sensitivity times a vector.

        :param numpy.array m: inversion model (nP,)
        :param numpy.array v: vector which we take sensitivity product with (nP,)
        :param SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM u: fields object
        :rtype numpy.array:
        :return: Jv (ndata,)
        """

        if f is None:
            f = self.fields(m)

        self.curModel = m

        Jv = self.dataPair(self.survey)

        for freq in self.survey.freqs:
            A = self.getA(freq)
            Ainv = self.Solver(
                A, **self.solverOpts
            )  # create the concept of Ainv (actually a solve)

            for src in self.survey.getSrcByFreq(freq):
                u_src = f[src, self._solutionType]
                dA_dm_v = self.getADeriv(freq, u_src, v)
                dRHS_dm_v = self.getRHSDeriv(freq, src, v)
                du_dm_v = Ainv * (-dA_dm_v + dRHS_dm_v)

                for rx in src.rxList:
                    df_dmFun = getattr(f, '_{0}Deriv'.format(rx.projField),
                                       None)
                    df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                    Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
            Ainv.clean()
        return Utils.mkvc(Jv)
Exemplo n.º 48
0
def E_field_from_SheetCurruent(XYZ, srcLoc, sig, t, E0=1., orientation='X', kappa=0., epsr=1.):
    """
        Computing Analytic Electric fields from Plane wave in a Wholespace
        TODO:
            Add description of parameters
    """

    XYZ = Utils.asArray_N_x_Dim(XYZ, 3)
    # Check
    if XYZ.shape[0] > 1 & t.shape[0] > 1:
        raise Exception("I/O type error: For multiple field locations only a single frequency can be specified.")

    mu = mu_0*(1+kappa)

    if orientation == "X":
        z = XYZ[:, 2]
        bunja = -E0*(mu*sig)**0.5 * z * np.exp(-(mu*sig*z**2) / (4*t))
        bunmo = 2 * np.pi**0.5 * t**1.5
        Ex = bunja / bunmo
        Ey = np.zeros_like(z)
        Ez = np.zeros_like(z)
        return Ex, Ey, Ez
    else:
        raise NotImplementedError()
Exemplo n.º 49
0
def hzAnalyticDipoleF(r, freq, sigma, secondary=True, mu=mu_0):
    """
    4.56 in Ward and Hohmann

    .. plot::

        import matplotlib.pyplot as plt
        from SimPEG import EM
        freq = np.logspace(-1, 6, 61)
        test = EM.Analytics.FDEM.hzAnalyticDipoleF(100, freq, 0.001, secondary=False)
        plt.loglog(freq, abs(test.real))
        plt.loglog(freq, abs(test.imag))
        plt.title('Response at $r$=100m')
        plt.xlabel('Frequency')
        plt.ylabel('Response')
        plt.legend(('real','imag'))
        plt.show()

    """
    r = np.abs(r)
    k = np.sqrt(-1j * 2. * np.pi * freq * mu * sigma)

    m = 1
    front = m / (2. * np.pi * (k**2) * (r**5))
    back = 9 - (9 + 9j * k * r - 4 * (k**2) * (r**2) - 1j * (k**3) *
                (r**3)) * np.exp(-1j * k * r)
    hz = front * back

    if secondary:
        hp = -1 / (4 * np.pi * r**3)
        hz = hz - hp

    if hz.ndim == 1:
        hz = Utils.mkvc(hz, 2)

    return hz
Exemplo n.º 50
0
    def bPrimary(self, prob):
        """
        The primary magnetic flux density from the analytic solution for
        magnetic fields from a dipole

        :param BaseFDEMProblem prob: FDEM problem
        :rtype: numpy.ndarray
        :return: primary magnetic field
        """

        formulation = prob._formulation
        coordinates = "cartesian"

        if formulation == 'EB':
            gridX = prob.mesh.gridFx
            gridY = prob.mesh.gridFy
            gridZ = prob.mesh.gridFz

        elif formulation == 'HJ':
            gridX = prob.mesh.gridEx
            gridY = prob.mesh.gridEy
            gridZ = prob.mesh.gridEz

        if prob.mesh._meshType == 'CYL':
            coordinates = "cylindrical"
            if prob.mesh.isSymmetric:
                bx = self._srcFct(gridX)[:, 0]
                bz = self._srcFct(gridZ)[:, 2]
                b = np.concatenate((bx, bz))
        else:
            bx = self._srcFct(gridX, coordinates=coordinates)[:, 0]
            by = self._srcFct(gridY, coordinates=coordinates)[:, 1]
            bz = self._srcFct(gridZ, coordinates=coordinates)[:, 2]
            b = np.concatenate((bx, by, bz))

        return Utils.mkvc(b)
    def getFields(self, itime):
        src = self.srcList[0]

        Ey = self.mesh.aveE2CC * self.f[src, "e", itime]
        Jy = Utils.sdiag(self.prb.sigma) * Ey

        self.Ey = Utils.mkvc(self.mirrorArray(Ey[self.activeCC],
                                              direction="y"))
        self.Jy = Utils.mkvc(self.mirrorArray(Jy[self.activeCC],
                                              direction="y"))
        self.Bx = Utils.mkvc(
            self.mirrorArray(self.Pfx * self.f[src, "b", itime],
                             direction="x"))
        self.Bz = Utils.mkvc(
            self.mirrorArray(self.Pfz * self.f[src, "b", itime],
                             direction="z"))
        self.dBxdt = Utils.mkvc(
            self.mirrorArray(-self.Pfx * self.mesh.edgeCurl *
                             self.f[src, "e", itime],
                             direction="x"))
        self.dBzdt = Utils.mkvc(
            self.mirrorArray(-self.Pfz * self.mesh.edgeCurl *
                             self.f[src, "e", itime],
                             direction="z"))
Exemplo n.º 52
0
def Intrgl_Fwr_Op(xn, yn, zn, rxLoc):
    """

    Magnetic forward operator in integral form

    flag        = 'ind' | 'full'

      1- ind : Magnetization fixed by user

      3- full: Full tensor matrix stored with shape([3*ndata, 3*nc])

    Return
    _G = Linear forward modeling operation

     """

    yn2, xn2, zn2 = np.meshgrid(yn[1:], xn[1:], zn[1:])
    yn1, xn1, zn1 = np.meshgrid(yn[0:-1], xn[0:-1], zn[0:-1])

    Yn = np.c_[Utils.mkvc(yn1), Utils.mkvc(yn2)]
    Xn = np.c_[Utils.mkvc(xn1), Utils.mkvc(xn2)]
    Zn = np.c_[Utils.mkvc(zn1), Utils.mkvc(zn2)]

    ndata = rxLoc.shape[0]

    # Pre-allocate forward matrix
    G = np.zeros((int(3 * ndata), 3))

    for ii in range(ndata):

        tx, ty, tz = PF.Magnetics.get_T_mat(Xn, Yn, Zn, rxLoc[ii, :])

        G[ii, :] = tx / 1e-9 * mu_0
        G[ii + ndata, :] = ty / 1e-9 * mu_0
        G[ii + 2 * ndata, :] = tz / 1e-9 * mu_0

    return G
def resolve_1Dinversions(mesh,
                         dobs,
                         src_height,
                         freqs,
                         m0,
                         mref,
                         mapping,
                         std=0.08,
                         floor=1e-14,
                         rxOffset=7.86):
    """
    Perform a single 1D inversion for a RESOLVE sounding for Horizontal
    Coplanar Coil data (both real and imaginary).

    :param discretize.CylMesh mesh: mesh used for the forward simulation
    :param numpy.array dobs: observed data
    :param float src_height: height of the source above the ground
    :param numpy.array freqs: frequencies
    :param numpy.array m0: starting model
    :param numpy.array mref: reference model
    :param Maps.IdentityMap mapping: mapping that maps the model to electrical conductivity
    :param float std: percent error used to construct the data misfit term
    :param float floor: noise floor used to construct the data misfit term
    :param float rxOffset: offset between source and receiver.
    """

    # ------------------- Forward Simulation ------------------- #
    # set up the receivers
    bzr = EM.FDEM.Rx.Point_bSecondary(np.array([[rxOffset, 0., src_height]]),
                                      orientation='z',
                                      component='real')

    bzi = EM.FDEM.Rx.Point_b(np.array([[rxOffset, 0., src_height]]),
                             orientation='z',
                             component='imag')

    # source location
    srcLoc = np.array([0., 0., src_height])
    srcList = [
        EM.FDEM.Src.MagDipole([bzr, bzi], freq, srcLoc, orientation='Z')
        for freq in freqs
    ]

    # construct a forward simulation
    survey = EM.FDEM.Survey(srcList)
    prb = EM.FDEM.Problem3D_b(mesh, sigmaMap=mapping, Solver=PardisoSolver)
    prb.pair(survey)

    # ------------------- Inversion ------------------- #
    # data misfit term
    survey.dobs = dobs
    dmisfit = DataMisfit.l2_DataMisfit(survey)
    uncert = abs(dobs) * std + floor
    dmisfit.W = 1. / uncert

    # regularization
    regMesh = Mesh.TensorMesh([mesh.hz[mapping.maps[-1].indActive]])
    reg = Regularization.Simple(regMesh)
    reg.mref = mref

    # optimization
    opt = Optimization.InexactGaussNewton(maxIter=10)

    # statement of the inverse problem
    invProb = InvProblem.BaseInvProblem(dmisfit, reg, opt)

    # Inversion directives and parameters
    target = Directives.TargetMisfit()
    inv = Inversion.BaseInversion(invProb, directiveList=[target])

    invProb.beta = 2.  # Fix beta in the nonlinear iterations
    reg.alpha_s = 1e-3
    reg.alpha_x = 1.
    prb.counter = opt.counter = Utils.Counter()
    opt.LSshorten = 0.5
    opt.remember('xc')

    # run the inversion
    mopt = inv.run(m0)
    return mopt, invProb.dpred, survey.dobs
def run(runIt=False, plotIt=True, saveIt=False, saveFig=False, cleanup=True):
    """
    Run the bookpurnong 1D stitched RESOLVE inversions.

    :param bool runIt: re-run the inversions? Default downloads and plots saved results
    :param bool plotIt: show the plots?
    :param bool saveIt: save the re-inverted results?
    :param bool saveFig: save the figure
    :param bool cleanup: remove the downloaded results
    """

    # download the data
    downloads, directory = download_and_unzip_data()

    # Load resolve data
    resolve = h5py.File(os.path.sep.join([directory, "booky_resolve.hdf5"]),
                        "r")

    river_path = resolve["river_path"][()]  # River path
    nSounding = resolve["data"].shape[0]  # the # of soundings

    # Bird height from surface
    b_height_resolve = resolve["src_elevation"][()]

    # fetch the frequencies we are considering
    cpi_inds = [0, 2, 6, 8, 10]  # Indices for HCP in-phase
    cpq_inds = [1, 3, 7, 9, 11]  # Indices for HCP quadrature
    frequency_cp = resolve["frequency_cp"][()]

    # build a mesh
    cs, ncx, ncz, npad = 1., 10., 10., 20
    hx = [(cs, ncx), (cs, npad, 1.3)]
    npad = 12
    temp = np.logspace(np.log10(1.), np.log10(12.), 19)
    temp_pad = temp[-1] * 1.3**np.arange(npad)
    hz = np.r_[temp_pad[::-1], temp[::-1], temp, temp_pad]
    mesh = Mesh.CylMesh([hx, 1, hz], '00C')
    active = mesh.vectorCCz < 0.

    # survey parameters
    rxOffset = 7.86  # tx-rx separation
    bp = -mu_0 / (4 * np.pi * rxOffset**3)  # primary magnetic field

    # re-run the inversion
    if runIt:

        # set up the mappings - we are inverting for 1D log conductivity
        # below the earth's surface.
        actMap = Maps.InjectActiveCells(mesh,
                                        active,
                                        np.log(1e-8),
                                        nC=mesh.nCz)
        mapping = Maps.ExpMap(mesh) * Maps.SurjectVertical1D(mesh) * actMap

        # build starting and reference model
        sig_half = 1e-1
        sig_air = 1e-8
        sigma = np.ones(mesh.nCz) * sig_air
        sigma[active] = sig_half
        m0 = np.log(1e-1) * np.ones(active.sum())  # starting model
        mref = np.log(1e-1) * np.ones(active.sum())  # reference model

        # initalize empty lists for storing inversion results
        mopt_re = []  # recovered model
        dpred_re = []  # predicted data
        dobs_re = []  # observed data

        # downsample the data for the inversion
        nskip = 40

        # set up a noise model
        # 10% for the 3 lowest frequencies, 15% for the two highest
        std = np.repeat(np.r_[np.ones(3) * 0.1, np.ones(2) * 0.15], 2)
        floor = abs(20 * bp * 1e-6)  # floor of 20ppm

        # loop over the soundings and invert each
        for rxind in range(nSounding):

            # convert data from ppm to magnetic field (A/m^2)
            dobs = np.c_[resolve["data"][rxind, :][cpi_inds].astype(float),
                         resolve["data"][rxind, :][cpq_inds].
                         astype(float)].flatten() * bp * 1e-6

            # perform the inversion
            src_height = b_height_resolve[rxind].astype(float)
            mopt, dpred, dobs = resolve_1Dinversions(mesh,
                                                     dobs,
                                                     src_height,
                                                     frequency_cp,
                                                     m0,
                                                     mref,
                                                     mapping,
                                                     std=std,
                                                     floor=floor)

            # add results to our list
            mopt_re.append(mopt)
            dpred_re.append(dpred)
            dobs_re.append(dobs)

        # save results
        mopt_re = np.vstack(mopt_re)
        dpred_re = np.vstack(dpred_re)
        dobs_re = np.vstack(dobs_re)

        if saveIt:
            np.save("mopt_re_final", mopt_re)
            np.save("dobs_re_final", dobs_re)
            np.save("dpred_re_final", dpred_re)

    mopt_re = resolve["mopt"][()]
    dobs_re = resolve["dobs"][()]
    dpred_re = resolve["dpred"][()]

    sigma = np.exp(mopt_re)
    indz = -7  # depth index

    # so that we can visually compare with literature (eg Viezzoli, 2010)
    cmap = "jet"

    # dummy figure for colobar
    fig = plt.figure()
    out = plt.scatter(np.ones(3),
                      np.ones(3),
                      c=np.linspace(-2, 1, 3),
                      cmap=cmap)
    plt.close(fig)

    # plot from the paper
    fs = 13  # fontsize
    # matplotlib.rcParams['font.size'] = fs
    plt.figure(figsize=(13, 7))
    ax0 = plt.subplot2grid((2, 3), (0, 0), rowspan=2, colspan=2)
    ax1 = plt.subplot2grid((2, 3), (0, 2))
    ax2 = plt.subplot2grid((2, 3), (1, 2))

    # titles of plots
    title = [("(a) Recovered model, %.1f m depth") %
             (-mesh.vectorCCz[active][indz]), "(b) Obs (Real 400 Hz)",
             "(c) Pred (Real 400 Hz)"]

    temp = sigma[:, indz]
    tree = cKDTree(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])))
    d, d_inds = tree.query(list(zip(resolve["xy"][:, 0], resolve["xy"][:, 1])),
                           k=20)
    w = 1. / (d + 100.)**2.
    w = Utils.sdiag(1. / np.sum(w, axis=1)) * (w)
    xy = resolve["xy"]
    temp = (temp.flatten()[d_inds] * w).sum(axis=1)
    Utils.plot2Ddata(xy,
                     temp,
                     ncontour=100,
                     scale="log",
                     dataloc=False,
                     contourOpts={
                         "cmap": cmap,
                         "vmin": 1e-2,
                         "vmax": 1e1
                     },
                     ax=ax0)
    ax0.plot(resolve["xy"][:, 0], resolve["xy"][:, 1], 'k.', alpha=0.02, ms=1)

    cb = plt.colorbar(out,
                      ax=ax0,
                      ticks=np.linspace(-2, 1, 4),
                      format="$10^{%.1f}$")
    cb.set_ticklabels(["0.01", "0.1", "1", "10"])
    cb.set_label("Conductivity (S/m)")
    ax0.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)

    # plot observed and predicted data
    freq_ind = 0
    axs = [ax1, ax2]
    temp_dobs = dobs_re[:, freq_ind].copy()
    ax1.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)
    out = Utils.plot2Ddata(resolve["xy"][()],
                           temp_dobs / abs(bp) * 1e6,
                           ncontour=100,
                           scale="log",
                           dataloc=False,
                           ax=ax1,
                           contourOpts={"cmap": "viridis"})
    vmin, vmax = out[0].get_clim()
    cb = plt.colorbar(out[0],
                      ticks=np.linspace(vmin, vmax, 3),
                      ax=ax1,
                      format="%.1e",
                      fraction=0.046,
                      pad=0.04)
    cb.set_label("Bz (ppm)")
    temp_dpred = dpred_re[:, freq_ind].copy()
    # temp_dpred[mask_:_data] = np.nan
    ax2.plot(river_path[:, 0], river_path[:, 1], 'k-', lw=0.5)
    Utils.plot2Ddata(resolve["xy"][()],
                     temp_dpred / abs(bp) * 1e6,
                     ncontour=100,
                     scale="log",
                     dataloc=False,
                     contourOpts={
                         "vmin": 10**vmin,
                         "vmax": 10**vmax,
                         "cmap": "viridis"
                     },
                     ax=ax2)
    cb = plt.colorbar(out[0],
                      ticks=np.linspace(vmin, vmax, 3),
                      ax=ax2,
                      format="%.1e",
                      fraction=0.046,
                      pad=0.04)
    cb.set_label("Bz (ppm)")

    for i, ax in enumerate([ax0, ax1, ax2]):
        xticks = [460000, 463000]
        yticks = [6195000, 6198000, 6201000]
        xloc, yloc = 462100.0, 6196500.0
        ax.set_xticks(xticks)
        ax.set_yticks(yticks)
        # ax.plot(xloc, yloc, 'wo')
        ax.plot(river_path[:, 0], river_path[:, 1], 'k', lw=0.5)

        ax.set_aspect("equal")
        ax.plot(resolve["xy"][:, 0],
                resolve["xy"][:, 1],
                'k.',
                alpha=0.02,
                ms=1)

        ax.set_yticklabels([str(f) for f in yticks])
        ax.set_ylabel("Northing (m)")
        ax.set_xlabel("Easting (m)")
        ax.set_title(title[i])

    plt.tight_layout()

    if plotIt:
        plt.show()

    if saveFig is True:
        fig.savefig("obspred_resolve.png", dpi=200)

    resolve.close()
    if cleanup:
        os.remove(downloads)
        shutil.rmtree(directory)
Exemplo n.º 55
0
# We will assume a vertical inducing field
H0 = (50000., 90., 0.)

# The magnetization is set along a different direction (induced + remanence)
M = np.array([45., 90.])

# Create grid of points for topography
# Lets create a simple Gaussian topo and set the active cells
[xx, yy] = np.meshgrid(np.linspace(-200, 200, 50), np.linspace(-200, 200, 50))
b = 100
A = 50
zz = A * np.exp(-0.5 * ((xx / b)**2. + (yy / b)**2.))

# We would usually load a topofile
topo = np.c_[Utils.mkvc(xx), Utils.mkvc(yy), Utils.mkvc(zz)]

# Create and array of observation points
xr = np.linspace(-100., 100., 20)
yr = np.linspace(-100., 100., 20)
X, Y = np.meshgrid(xr, yr)
Z = A * np.exp(-0.5 * ((X / b)**2. + (Y / b)**2.)) + 5

# Create a MAGsurvey
xyzLoc = np.c_[Utils.mkvc(X.T), Utils.mkvc(Y.T), Utils.mkvc(Z.T)]
rxLoc = PF.BaseMag.RxObs(xyzLoc)
srcField = PF.BaseMag.SrcField([rxLoc], param=H0)
survey = PF.BaseMag.LinearSurvey(srcField)

# Here how the topography looks with a quick interpolation, just a Gaussian...
tri = sp.spatial.Delaunay(topo)
Exemplo n.º 56
0
def MagneticDipoleWholeSpace(XYZ, srcLoc, sig, f, moment=1., orientation='X', mu = mu_0):
    """
    Analytical solution for a dipole in a whole-space.

    Equation 2.57 of Ward and Hohmann

    TODOs:
        - set it up to instead take a mesh & survey
        - add E-fields
        - handle multiple frequencies
        - add divide by zero safety


    .. plot::

        from SimPEG import EM
        import matplotlib.pyplot as plt
        from scipy.constants import mu_0
        freqs = np.logspace(-2,5,100)
        Bx, By, Bz = EM.Analytics.FDEM.MagneticDipoleWholeSpace([0,100,0], [0,0,0], 1e-2, freqs, moment=1, orientation='Z')
        plt.loglog(freqs, np.abs(Bz.real)/mu_0, 'b')
        plt.loglog(freqs, np.abs(Bz.imag)/mu_0, 'r')
        plt.legend(('real','imag'))
        plt.show()


    """

    XYZ = Utils.asArray_N_x_Dim(XYZ, 3)

    dx = XYZ[:,0]-srcLoc[0]
    dy = XYZ[:,1]-srcLoc[1]
    dz = XYZ[:,2]-srcLoc[2]

    r  = np.sqrt( dx**2. + dy**2. + dz**2.)
    k  = np.sqrt( -1j*2.*np.pi*f*mu*sig )
    kr = k*r

    front = moment / (4.*pi * r**3.) * np.exp(-1j*kr)
    mid   = -kr**2. + 3.*1j*kr + 3.

    if orientation.upper() == 'X':
        Hx = front*( (dx/r)**2. * mid + (kr**2. - 1j*kr - 1.) )
        Hy = front*( (dx*dy/r**2.) * mid )
        Hz = front*( (dx*dz/r**2.) * mid )

    elif orientation.upper() == 'Y':
        Hx = front*( (dy*dx/r**2.) * mid )
        Hy = front*( (dy/r)**2. * mid + (kr**2. - 1j*kr - 1.) )
        Hz = front*( (dy*dz/r**2.) * mid )

    elif orientation.upper() == 'Z':
        Hx = front*( (dx*dz/r**2.) * mid )
        Hy = front*( (dy*dz/r**2.) * mid )
        Hz = front*( (dz/r)**2. * mid + (kr**2. - 1j*kr - 1.) )

    Bx = mu*Hx
    By = mu*Hy
    Bz = mu*Hz

    if Bx.ndim is 1:
        Bx = Utils.mkvc(Bx,2)

    if By.ndim is 1:
        By = Utils.mkvc(By,2)

    if Bz.ndim is 1:
        Bz = Utils.mkvc(Bz,2)

    return Bx, By, Bz
Exemplo n.º 57
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
Exemplo n.º 58
0
overb = (mesh.gridCC[:, 1] > -overburden_extent) & (mesh.gridCC[:, 1] <= 0)
mtrue[overb] = ln_over * np.ones_like(mtrue[overb]) + norm(
    noisemean, noisevar).rvs(np.prod((mtrue[overb]).shape))

csph = (np.sqrt((mesh.gridCC[:, 1] - z0)**2. +
                (mesh.gridCC[:, 0] - x0)**2.)) < r0
mtrue[csph] = ln_sigc * np.ones_like(mtrue[csph]) + norm(
    noisemean, noisevar).rvs(np.prod((mtrue[csph]).shape))

#Define the sphere limit
rsph = (np.sqrt((mesh.gridCC[:, 1] - z1)**2. +
                (mesh.gridCC[:, 0] - x1)**2.)) < r1
mtrue[rsph] = ln_sigr * np.ones_like(mtrue[rsph]) + norm(
    noisemean, noisevar).rvs(np.prod((mtrue[rsph]).shape))

mtrue = Utils.mkvc(mtrue)

mesh.plotGrid()
plt.gca().set_xlim([-10, 10])
plt.gca().set_ylim([-10, 0])
xyzlim = np.r_[[[-10., 10.], [-10., 1.]]]
actind, meshCore = Utils.meshutils.ExtractCoreMesh(xyzlim, mesh)

plt.hist(mtrue[actind], bins=50, normed=True)

fig0 = plt.figure()
ax0 = fig0.add_subplot(111)
mm = meshCore.plotImage(mtrue[actind], ax=ax0)
plt.colorbar(mm[0])
ax0.set_aspect("equal")
#plt.show()
Exemplo n.º 59
0
def run(plotIt=True):
    """
        Mesh: Plotting with defining range
        ==================================

        When using a large Mesh with the cylindrical code, it is advantageous
        to define a :code:`range_x` and :code:`range_y` when plotting with
        vectors. In this case, only the region inside of the range is
        interpolated. In particular, you often want to ignore padding cells.

    """

    # ## Model Parameters
    #
    # We define a
    # - resistive halfspace and
    # - conductive sphere
    #    - radius of 30m
    #    - center is 50m below the surface

    # electrical conductivities in S/m
    sig_halfspace = 1e-6
    sig_sphere = 1e0
    sig_air = 1e-8

    # depth to center, radius in m
    sphere_z = -50.
    sphere_radius = 30.

    # ## Survey Parameters
    #
    # - Transmitter and receiver 20m above the surface
    # - Receiver offset from transmitter by 8m horizontally
    # - 25 frequencies, logaritmically between $10$ Hz and $10^5$ Hz

    boom_height = 20.
    rx_offset = 8.
    freqs = np.r_[1e1, 1e5]

    # source and receiver location in 3D space
    src_loc = np.r_[0., 0., boom_height]
    rx_loc = np.atleast_2d(np.r_[rx_offset, 0., boom_height])

    # print the min and max skin depths to make sure mesh is fine enough and
    # extends far enough

    def skin_depth(sigma, f):
        return 500. / np.sqrt(sigma * f)

    print('Minimum skin depth (in sphere): {:.2e} m '.format(
        skin_depth(sig_sphere, freqs.max())))
    print('Maximum skin depth (in background): {:.2e} m '.format(
        skin_depth(sig_halfspace, freqs.min())))

    # ## Mesh
    #
    # Here, we define a cylindrically symmetric tensor mesh.
    #
    # ### Mesh Parameters
    #
    # For the mesh, we will use a cylindrically symmetric tensor mesh. To
    # construct a tensor mesh, all that is needed is a vector of cell widths in
    # the x and z-directions. We will define a core mesh region of uniform cell
    # widths and a padding region where the cell widths expand "to infinity".

    # x-direction
    csx = 2  # core mesh cell width in the x-direction
    ncx = np.ceil(
        1.2 * sphere_radius / csx
    )  # number of core x-cells (uniform mesh slightly beyond sphere radius)
    npadx = 50  # number of x padding cells

    # z-direction
    csz = 1  # core mesh cell width in the z-direction
    ncz = np.ceil(
        1.2 * (boom_height - (sphere_z - sphere_radius)) / csz
    )  # number of core z-cells (uniform cells slightly below bottom of sphere)
    npadz = 52  # number of z padding cells

    # padding factor (expand cells to infinity)
    pf = 1.3

    # cell spacings in the x and z directions
    hx = Utils.meshTensor([(csx, ncx), (csx, npadx, pf)])
    hz = Utils.meshTensor([(csz, npadz, -pf), (csz, ncz), (csz, npadz, pf)])

    # define a SimPEG mesh
    mesh = Mesh.CylMesh([hx, 1, hz],
                        x0=np.r_[0., 0., -hz.sum() / 2. - boom_height])

    # ### Plot the mesh
    #
    # Below, we plot the mesh. The cyl mesh is rotated around x=0. Ensure that
    # each dimension extends beyond the maximum skin depth.
    #
    # Zoom in by changing the xlim and zlim.

    # X and Z limits we want to plot to. Try
    xlim = np.r_[0., 2.5e6]
    zlim = np.r_[-2.5e6, 2.5e6]

    fig, ax = plt.subplots(1, 1)
    mesh.plotGrid(ax=ax)

    ax.set_title('Simulation Mesh')
    ax.set_xlim(xlim)
    ax.set_ylim(zlim)

    print('The maximum skin depth is (in background): {:.2e} m. '
          'Does the mesh go sufficiently past that?'.format(
              skin_depth(sig_halfspace, freqs.min())))

    # ## Put Model on Mesh
    #
    # Now that the model parameters and mesh are defined, we can define
    # electrical conductivity on the mesh.
    #
    # The electrical conductivity is defined at cell centers when using the
    # finite volume method. So here, we define a vector that contains an
    # electrical conductivity value for every cell center.

    # create a vector that has one entry for every cell center
    sigma = sig_air * np.ones(
        mesh.nC)  # start by defining the conductivity of the air everwhere
    sigma[mesh.gridCC[:, 2] <
          0.] = sig_halfspace  # assign halfspace cells below the earth

    # indices of the sphere (where (x-x0)**2 + (z-z0)**2 <= R**2)
    sphere_ind = ((mesh.gridCC[:, 0]**2 +
                   (mesh.gridCC[:, 2] - sphere_z)**2) <= sphere_radius**2)
    sigma[sphere_ind] = sig_sphere  # assign the conductivity of the sphere

    # Plot a cross section of the conductivity model
    fig, ax = plt.subplots(1, 1)
    cb = plt.colorbar(mesh.plotImage(np.log10(sigma), ax=ax, mirror=True)[0])

    # plot formatting and titles
    cb.set_label('$\log_{10}\sigma$', fontsize=13)
    ax.axis('equal')
    ax.set_xlim([-120., 120.])
    ax.set_ylim([-100., 30.])
    ax.set_title('Conductivity Model')

    # ## Set up the Survey
    #
    # Here, we define sources and receivers. For this example, the receivers
    # are magnetic flux recievers, and are only looking at the secondary field
    # (eg. if a bucking coil were used to cancel the primary). The source is a
    # vertical magnetic dipole with unit moment.

    # Define the receivers, we will sample the real secondary magnetic flux
    # density as well as the imaginary magnetic flux density

    bz_r = FDEM.Rx.Point_bSecondary(
        locs=rx_loc, orientation='z',
        component='real')  # vertical real b-secondary
    bz_i = FDEM.Rx.Point_b(
        locs=rx_loc, orientation='z',
        component='imag')  # vertical imag b (same as b-secondary)

    rxList = [bz_r, bz_i]  # list of receivers

    # Define the list of sources - one source for each frequency. The source is
    # a point dipole oriented in the z-direction

    srcList = [
        FDEM.Src.MagDipole(rxList, f, src_loc, orientation='z') for f in freqs
    ]

    print(
        'There are {nsrc} sources (same as the number of frequencies - {nfreq}). '
        'Each source has {nrx} receivers sampling the resulting b-fields'.
        format(nsrc=len(srcList), nfreq=len(freqs), nrx=len(rxList)))

    # ## Set up Forward Simulation
    #
    # A forward simulation consists of a paired SimPEG problem and Survey.
    # For this example, we use the E-formulation of Maxwell's equations,
    # solving the second-order system for the electric field, which is defined
    # on the cell edges of the mesh. This is the `prob` variable below. The
    # `survey` takes the source list which is used to construct the RHS for the
    # problem. The source list also contains the receiver information, so the
    # `survey` knows how to sample fields and fluxes that are produced by
    # solving the `prob`.

    # define a problem - the statement of which discrete pde system we want to
    # solve
    prob = FDEM.Problem3D_e(mesh, sigmaMap=Maps.IdentityMap(mesh))
    prob.solver = Solver

    survey = FDEM.Survey(srcList)

    # tell the problem and survey about each other - so the RHS can be
    # constructed for the problem and the
    # resulting fields and fluxes can be sampled by the receiver.
    prob.pair(survey)

    # ### Solve the forward simulation
    #
    # Here, we solve the problem for the fields everywhere on the mesh.
    fields = prob.fields(sigma)

    # ### Plot the fields
    #
    # Lets look at the physics!

    # log-scale the colorbar
    from matplotlib.colors import LogNorm

    fig, ax = plt.subplots(1, 2, figsize=(12, 6))

    def plotMe(field, ax):
        plt.colorbar(mesh.plotImage(field,
                                    vType='F',
                                    view='vec',
                                    range_x=[-100., 100.],
                                    range_y=[-180., 60.],
                                    pcolorOpts={
                                        'norm': LogNorm(),
                                        'cmap': plt.get_cmap('viridis')
                                    },
                                    streamOpts={'color': 'k'},
                                    ax=ax,
                                    mirror=True)[0],
                     ax=ax)

    plotMe(fields[srcList[0], 'bSecondary'].real, ax[0])
    ax[0].set_title('Real B-Secondary, {}Hz'.format(freqs[0]))

    plotMe(fields[srcList[1], 'bSecondary'].real, ax[1])
    ax[1].set_title('Real B-Secondary, {}Hz'.format(freqs[1]))

    plt.tight_layout()

    if plotIt:
        plt.show()
Exemplo n.º 60
0
invProb = InvProblem.BaseInvProblem(dmis, regT, opt)

# Directives for Inversions
beta = Directives.BetaEstimate_ByEig(beta0_ratio=1e+1)
Target = Directives.TargetMisfit()
betaSched = Directives.BetaSchedule(coolingFactor=5., coolingRate=2)

inv = Inversion.BaseInversion(invProb, directiveList=[beta, Target, betaSched])
# Run Inversion
minv = inv.run(m0)

# Final Plot
############

fig, ax = plt.subplots(2, 2, figsize=(12, 6))
ax = Utils.mkvc(ax)

cyl0v = getCylinderPoints(x0, z0, r0)
cyl1v = getCylinderPoints(x1, z1, r1)

cyl0h = getCylinderPoints(x0, y0, r0)
cyl1h = getCylinderPoints(x1, y1, r1)

clim = [(mtrue[actind]).min(), (mtrue[actind]).max()]

dat = meshCore.plotSlice(((mtrue[actind])),
                         ax=ax[0],
                         normal='Y',
                         clim=clim,
                         ind=int(ncy / 2))
ax[0].set_title('Ground Truth, Vertical')