Example #1
0
 def S_eDeriv_m(self, problem, v, adjoint=False):
     '''
     Get the derivative of S_e wrt to sigma (m)
     '''
     # Need to deal with
     if problem.mesh.dim == 1:
         # Need to use the faceInnerProduct
         MsigmaDeriv = problem.mesh.getFaceInnerProductDeriv(
             problem.curModel.sigma)(
                 self.ePrimary(problem)[:, 1]) * problem.curModel.sigmaDeriv
         # MsigmaDeriv = ( MsigmaDeriv * MsigmaDeriv.T)**2
     if problem.mesh.dim == 2:
         pass
     if problem.mesh.dim == 3:
         # Need to take the derivative of both u_px and u_py
         ePri = self.ePrimary(problem)
         # MsigmaDeriv = problem.MeSigmaDeriv(ePri[:,0]) + problem.MeSigmaDeriv(ePri[:,1])
         # MsigmaDeriv = problem.MeSigmaDeriv(np.sum(ePri,axis=1))
         if adjoint:
             return sp.hstack((problem.MeSigmaDeriv(
                 ePri[:, 0]).T, problem.MeSigmaDeriv(ePri[:, 1]).T)) * v
         else:
             return np.hstack(
                 (mkvc(problem.MeSigmaDeriv(ePri[:, 0]) * v,
                       2), mkvc(problem.MeSigmaDeriv(ePri[:, 1]) * v, 2)))
     if adjoint:
         #
         return MsigmaDeriv.T * v
     else:
         # v should be nC size
         return MsigmaDeriv * v
Example #2
0
 def S_eDeriv_m(self, problem, v, adjoint=False):
     """
     Get the derivative of S_e wrt to sigma (m)
     """
     # Need to deal with
     if problem.mesh.dim == 1:
         # Need to use the faceInnerProduct
         MsigmaDeriv = (
             problem.mesh.getFaceInnerProductDeriv(problem.curModel.sigma)(self.ePrimary(problem)[:, 1])
             * problem.curModel.sigmaDeriv
         )
         # MsigmaDeriv = ( MsigmaDeriv * MsigmaDeriv.T)**2
     if problem.mesh.dim == 2:
         pass
     if problem.mesh.dim == 3:
         # Need to take the derivative of both u_px and u_py
         ePri = self.ePrimary(problem)
         # MsigmaDeriv = problem.MeSigmaDeriv(ePri[:,0]) + problem.MeSigmaDeriv(ePri[:,1])
         # MsigmaDeriv = problem.MeSigmaDeriv(np.sum(ePri,axis=1))
         if adjoint:
             return sp.hstack((problem.MeSigmaDeriv(ePri[:, 0]).T, problem.MeSigmaDeriv(ePri[:, 1]).T)) * v
         else:
             return np.hstack(
                 (mkvc(problem.MeSigmaDeriv(ePri[:, 0]) * v, 2), mkvc(problem.MeSigmaDeriv(ePri[:, 1]) * v, 2))
             )
     if adjoint:
         #
         return MsigmaDeriv.T * v
     else:
         # v should be nC size
         return MsigmaDeriv * v
Example #3
0
    def test_invXXXBlockDiagonal(self):
        a = [np.random.rand(5, 1) for i in range(4)]

        B = inv2X2BlockDiagonal(*a)

        A = sp.vstack((sp.hstack((sdiag(a[0]), sdiag(a[1]))),
                       sp.hstack((sdiag(a[2]), sdiag(a[3])))))

        Z2 = B*A - sp.identity(10)
        self.assertTrue(np.linalg.norm(Z2.todense().ravel(), 2) < TOL)

        a = [np.random.rand(5, 1) for i in range(9)]
        B = inv3X3BlockDiagonal(*a)

        A = sp.vstack((sp.hstack((sdiag(a[0]), sdiag(a[1]),  sdiag(a[2]))),
                       sp.hstack((sdiag(a[3]), sdiag(a[4]),  sdiag(a[5]))),
                       sp.hstack((sdiag(a[6]), sdiag(a[7]),  sdiag(a[8])))))

        Z3 = B*A - sp.identity(15)

        self.assertTrue(np.linalg.norm(Z3.todense().ravel(), 2) < TOL)
Example #4
0
    def getADeriv_m(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        """

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack(( self.MeSigmaDeriv( u['e_pxSolution'] ).T, self.MeSigmaDeriv(u['e_pySolution'] ).T ))*v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(( mkvc(self.MeSigmaDeriv( u['e_pxSolution'] )*v,2), mkvc( self.MeSigmaDeriv(u['e_pySolution'] )*v,2) ))
        return 1j * omega(freq) * dMe_dsigV
Example #5
0
    def test_invXXXBlockDiagonal(self):
        a = [np.random.rand(5, 1) for i in range(4)]

        B = inv2X2BlockDiagonal(*a)

        A = sp.vstack((sp.hstack(
            (sdiag(a[0]), sdiag(a[1]))), sp.hstack(
                (sdiag(a[2]), sdiag(a[3])))))

        Z2 = B * A - sp.identity(10)
        self.assertTrue(np.linalg.norm(Z2.todense().ravel(), 2) < TOL)

        a = [np.random.rand(5, 1) for i in range(9)]
        B = inv3X3BlockDiagonal(*a)

        A = sp.vstack((sp.hstack((sdiag(a[0]), sdiag(a[1]), sdiag(a[2]))),
                       sp.hstack((sdiag(a[3]), sdiag(a[4]), sdiag(a[5]))),
                       sp.hstack((sdiag(a[6]), sdiag(a[7]), sdiag(a[8])))))

        Z3 = B * A - sp.identity(15)

        self.assertTrue(np.linalg.norm(Z3.todense().ravel(), 2) < TOL)
Example #6
0
    def getInterpolationMat(self, loc, locType, zerosOutside=False):
        """ Produces interpolation matrix

        :param numpy.ndarray loc: Location of points to interpolate to
        :param str locType: What to interpolate (see below)
        :rtype: scipy.sparse.csr.csr_matrix
        :return: M, the interpolation matrix

        locType can be::

            'Ex'    -> x-component of field defined on edges
            'Ey'    -> y-component of field defined on edges
            'Ez'    -> z-component of field defined on edges
            'Fx'    -> x-component of field defined on faces
            'Fy'    -> y-component of field defined on faces
            'Fz'    -> z-component of field defined on faces
            'N'     -> scalar field defined on nodes
            'CC'    -> scalar field defined on cell centers
        """
        if self._meshType == 'CYL' and self.isSymmetric and locType in ['Ex','Ez','Fy']:
            raise Exception('Symmetric CylMesh does not support %s interpolation, as this variable does not exist.' % locType)

        loc = Utils.asArray_N_x_Dim(loc, self.dim)

        if zerosOutside is False:
            assert np.all(self.isInside(loc)), "Points outside of mesh"
        else:
            indZeros = np.logical_not(self.isInside(loc))
            loc[indZeros, :] = np.array([v.mean() for v in self.getTensor('CC')])

        if locType in ['Fx','Fy','Fz','Ex','Ey','Ez']:
            ind = {'x':0, 'y':1, 'z':2}[locType[1]]
            assert self.dim >= ind, 'mesh is not high enough dimension.'
            nF_nE = self.vnF if 'F' in locType else self.vnE
            components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE]
            components[ind] = Utils.interpmat(loc, *self.getTensor(locType))
            # remove any zero blocks (hstack complains)
            components = [comp for comp in components if comp.shape[1] > 0]
            Q = sp.hstack(components)
        elif locType in ['CC', 'N']:
            Q = Utils.interpmat(loc, *self.getTensor(locType))
        else:
            raise NotImplementedError('getInterpolationMat: locType=='+locType+' and mesh.dim=='+str(self.dim))

        if zerosOutside:
            Q[indZeros, :] = 0

        return Q.tocsr()
Example #7
0
    def getADeriv_m(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        """

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack((self.MeSigmaDeriv(u['e_pxSolution']).T,
                                   self.MeSigmaDeriv(u['e_pySolution']).T)) * v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (mkvc(self.MeSigmaDeriv(u['e_pxSolution']) * v,
                      2), mkvc(self.MeSigmaDeriv(u['e_pySolution']) * v, 2)))
        return 1j * omega(freq) * dMe_dsigV
Example #8
0
    def getADeriv_m(self, freq, u, v, adjoint=False):

        # Nee to account for both the polarizations
        # dMe_dsig = (self.MeSigmaDeriv( u['e_pxSolution'] ) + self.MeSigmaDeriv( u['e_pySolution'] ))
        # dMe_dsig = (self.MeSigmaDeriv( u['e_pxSolution'] +  u['e_pySolution'] ))

        # # dMe_dsig = self.MeSigmaDeriv( u )
        # if adjoint:
        #     return 1j * omega(freq) * ( dMe_dsig.T * v ) # As in simpegEM

        # return 1j * omega(freq) * ( dMe_dsig * v ) # As in simpegEM

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack((self.MeSigmaDeriv(u['e_pxSolution']).T,
                                   self.MeSigmaDeriv(u['e_pySolution']).T)) * v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (mkvc(self.MeSigmaDeriv(u['e_pxSolution']) * v,
                      2), mkvc(self.MeSigmaDeriv(u['e_pySolution']) * v, 2)))
        return 1j * omega(freq) * dMe_dsigV
Example #9
0
    def getInterpolationMat(self, loc, locType='CC', zerosOutside=False):
        """ Produces interpolation matrix

        :param numpy.ndarray loc: Location of points to interpolate to
        :param str locType: What to interpolate (see below)
        :rtype: scipy.sparse.csr.csr_matrix
        :return: M, the interpolation matrix

        locType can be::

            'Ex'    -> x-component of field defined on edges
            'Ey'    -> y-component of field defined on edges
            'Ez'    -> z-component of field defined on edges
            'Fx'    -> x-component of field defined on faces
            'Fy'    -> y-component of field defined on faces
            'Fz'    -> z-component of field defined on faces
            'N'     -> scalar field defined on nodes
            'CC'    -> scalar field defined on cell centers
            'CCVx'  -> x-component of vector field defined on cell centers
            'CCVy'  -> y-component of vector field defined on cell centers
            'CCVz'  -> z-component of vector field defined on cell centers
        """
        if self._meshType == 'CYL' and self.isSymmetric and locType in [
                'Ex', 'Ez', 'Fy'
        ]:
            raise Exception(
                'Symmetric CylMesh does not support %s interpolation, as this variable does not exist.'
                % locType)

        loc = Utils.asArray_N_x_Dim(loc, self.dim)

        if zerosOutside is False:
            assert np.all(self.isInside(loc)), "Points outside of mesh"
        else:
            indZeros = np.logical_not(self.isInside(loc))
            loc[indZeros, :] = np.array(
                [v.mean() for v in self.getTensor('CC')])

        if locType in ['Fx', 'Fy', 'Fz', 'Ex', 'Ey', 'Ez']:
            ind = {'x': 0, 'y': 1, 'z': 2}[locType[1]]
            assert self.dim >= ind, 'mesh is not high enough dimension.'
            nF_nE = self.vnF if 'F' in locType else self.vnE
            components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE]
            components[ind] = Utils.interpmat(loc, *self.getTensor(locType))
            # remove any zero blocks (hstack complains)
            components = [comp for comp in components if comp.shape[1] > 0]
            Q = sp.hstack(components)
        elif locType in ['CC', 'N']:
            Q = Utils.interpmat(loc, *self.getTensor(locType))
        elif locType in ['CCVx', 'CCVy', 'CCVz']:
            Q = Utils.interpmat(loc, *self.getTensor('CC'))
            Z = Utils.spzeros(loc.shape[0], self.nC)
            if locType == 'CCVx':
                Q = sp.hstack([Q, Z, Z])
            elif locType == 'CCVy':
                Q = sp.hstack([Z, Q, Z])
            elif locType == 'CCVz':
                Q = sp.hstack([Z, Z, Q])

        else:
            raise NotImplementedError('getInterpolationMat: locType==' +
                                      locType + ' and mesh.dim==' +
                                      str(self.dim))

        if zerosOutside:
            Q[indZeros, :] = 0

        return Q.tocsr()
Example #10
0
    def _fastInnerProductDeriv(self, projType, prop, invProp=False,
                               invMat=False):
        """
            :param str projType: 'E' or 'F'
            :param TensorType tensorType: type of the tensor
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: function
            :return: dMdmu, the derivative of the inner product matrix
        """
        assert projType in ['F', 'E'], ("projType must be 'F' for faces or 'E'"
                                        " for edges")

        tensorType = Utils.TensorType(self, prop)

        dMdprop = None

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

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


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

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

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

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

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

        if dMdprop is not None:
            def innerProductDeriv(v=None):
                if v is None:
                    warnings.warn("Depreciation Warning: "
                                  "TensorMesh.innerProductDeriv."
                                  " You should be supplying a vector. "
                                  "Use: sdiag(u)*dMdprop", FutureWarning)
                    return dMdprop
                return Utils.sdiag(v) * dMdprop
            return innerProductDeriv
        else:
            return None
Example #11
0
    def _fastInnerProductDeriv(self, projType, prop, invProp=False, invMat=False):
        """
            :param str projType: 'E' or 'F'
            :param TensorType tensorType: type of the tensor
            :param bool invProp: inverts the material property
            :param bool invMat: inverts the matrix
            :rtype: function
            :return: dMdmu, the derivative of the inner product matrix
        """
        assert projType in ["F", "E"], "projType must be 'F' for faces or 'E'" " for edges"

        tensorType = Utils.TensorType(self, prop)

        dMdprop = None

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

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

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

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

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

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

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

        if dMdprop is not None:

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

            return innerProductDeriv
        else:
            return None
Example #12
0
    def getInterpolationMat(self, loc, locType="CC", zerosOutside=False):
        """ Produces interpolation matrix

        :param numpy.ndarray loc: Location of points to interpolate to
        :param str locType: What to interpolate (see below)
        :rtype: scipy.sparse.csr_matrix
        :return: M, the interpolation matrix

        locType can be::

            'Ex'    -> x-component of field defined on edges
            'Ey'    -> y-component of field defined on edges
            'Ez'    -> z-component of field defined on edges
            'Fx'    -> x-component of field defined on faces
            'Fy'    -> y-component of field defined on faces
            'Fz'    -> z-component of field defined on faces
            'N'     -> scalar field defined on nodes
            'CC'    -> scalar field defined on cell centers
            'CCVx'  -> x-component of vector field defined on cell centers
            'CCVy'  -> y-component of vector field defined on cell centers
            'CCVz'  -> z-component of vector field defined on cell centers
        """
        if self._meshType == "CYL" and self.isSymmetric and locType in ["Ex", "Ez", "Fy"]:
            raise Exception(
                "Symmetric CylMesh does not support {0!s} interpolation, as this variable does not exist.".format(
                    locType
                )
            )

        loc = Utils.asArray_N_x_Dim(loc, self.dim)

        if zerosOutside is False:
            assert np.all(self.isInside(loc)), "Points outside of mesh"
        else:
            indZeros = np.logical_not(self.isInside(loc))
            loc[indZeros, :] = np.array([v.mean() for v in self.getTensor("CC")])

        if locType in ["Fx", "Fy", "Fz", "Ex", "Ey", "Ez"]:
            ind = {"x": 0, "y": 1, "z": 2}[locType[1]]
            assert self.dim >= ind, "mesh is not high enough dimension."
            nF_nE = self.vnF if "F" in locType else self.vnE
            components = [Utils.spzeros(loc.shape[0], n) for n in nF_nE]
            components[ind] = Utils.interpmat(loc, *self.getTensor(locType))
            # remove any zero blocks (hstack complains)
            components = [comp for comp in components if comp.shape[1] > 0]
            Q = sp.hstack(components)
        elif locType in ["CC", "N"]:
            Q = Utils.interpmat(loc, *self.getTensor(locType))
        elif locType in ["CCVx", "CCVy", "CCVz"]:
            Q = Utils.interpmat(loc, *self.getTensor("CC"))
            Z = Utils.spzeros(loc.shape[0], self.nC)
            if locType == "CCVx":
                Q = sp.hstack([Q, Z, Z])
            elif locType == "CCVy":
                Q = sp.hstack([Z, Q, Z])
            elif locType == "CCVz":
                Q = sp.hstack([Z, Z, Q])

        else:
            raise NotImplementedError("getInterpolationMat: locType==" + locType + " and mesh.dim==" + str(self.dim))

        if zerosOutside:
            Q[indZeros, :] = 0

        return Q.tocsr()
Example #13
0
 def _b_pySecondaryDeriv_u(self, src, v, adjoint=False):
     # C = sp.kron(self.mesh.edgeCurl,[[0,0],[0,1]])
     C = sp.hstack((Utils.spzeros(self.mesh.nF, self.mesh.nE), self.mesh.edgeCurl))  # This works for adjoint = None
     if adjoint:
         return -1.0 / (1j * omega(src.freq)) * (C.T * v)
     return -1.0 / (1j * omega(src.freq)) * (C * v)
Example #14
0
 def _b_pySecondaryDeriv_u(self, src, v, adjoint = False):
     # C = sp.kron(self.mesh.edgeCurl,[[0,0],[0,1]])
     C = sp.hstack((Utils.spzeros(self.mesh.nF,self.mesh.nE),self.mesh.edgeCurl)) # This works for adjoint = None
     if adjoint:
         return - 1./(1j*omega(src.freq)) * (C.T * v)
     return - 1./(1j*omega(src.freq)) * (C * v)