Ejemplo n.º 1
0
    def Jfull(self, m, 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)
        P = self.survey.evalDeriv(f, m)
        AinvB = Ainv * B
        z = np.zeros((self.mesh.nC, B.shape[1]))
        zAinvB = np.vstack((z, AinvB))
        J = P * zAinvB
        return J
Ejemplo n.º 2
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
Ejemplo n.º 3
0
 def Dz(self):
     if self.mesh.dim == 1:
         Dz = self.mesh.faceDivx
     elif self.mesh.dim == 2:
         Dz = sp.hstack((Utils.spzeros(
             self.mesh.nC, self.mesh.vnF[0]), self.mesh.faceDivy),
                        format='csr')
     elif self.mesh.dim == 3:
         Dz = sp.hstack(
             (Utils.spzeros(self.mesh.nC, self.mesh.vnF[0] +
                            self.mesh.vnF[1]), self.mesh.faceDivz),
             format='csr')
     return Dz
Ejemplo n.º 4
0
    def Dz(self):
        if self.mesh.dim == 1:
            return self.mesh.faceDivx

        if self.mesh.dim == 2:
            mats = (
                Utils.spzeros(self.mesh.nC, self.mesh.vnF[0]),
                self.mesh.faceDivy
            )
        elif self.mesh.dim == 3:
            mats = (
                Utils.spzeros(self.mesh.nC, self.mesh.vnF[0]+self.mesh.vnF[1]),
                self.mesh.faceDivz
            )
        return sp.hstack(mats, format='csr')
Ejemplo n.º 5
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
Ejemplo n.º 6
0
 def getADeriv_sigma(self, freq, f, v, adjoint=False):
     Ex = f[:self.mesh.nC]
     dMcc_dsig = self.MccSigmaDeriv(Ex)
     if adjoint:
         return sp.hstack(
             (Utils.spzeros(self.mesh.nC, self.mesh.nN), dMcc_dsig.T)) * v
     else:
         return np.r_[np.zeros(self.mesh.nC + 1), dMcc_dsig * v]
Ejemplo n.º 7
0
 def getADeriv_sigma(self, freq, f, v, adjoint=False):
     Ex = f[:self.mesh.nC]
     dMcc_dsig = self.MccSigmaDeriv(Ex)
     if adjoint:
         return sp.hstack(
             (Utils.spzeros(self.mesh.nC, self.mesh.nN), dMcc_dsig.T)
             ) * v
     else:
         return np.r_[np.zeros(self.mesh.nC+1), dMcc_dsig*v]
Ejemplo n.º 8
0
    def _b_pyDeriv_u(self, src, du_dm_v, adjoint=False):
        """ Derivative of b_py with wrt u

        :param SimPEG.NSEM.src src: The source of the problem
        :param numpy.ndarray du_dm_v: vector to take product with. Size (nF,) when adjoint=True, (nU,) when adjoint=False
        :param bool adjoint: adjoint?
        :rtype: numpy.ndarray
        :return: The calculated derivative, size (nU,) when adjoint=True. (nF,) when adjoint=False
        """
        # Primary does not depend on u
        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 * du_dm_v)
        return - 1./(1j*omega(src.freq)) * (C * du_dm_v)
Ejemplo n.º 9
0
    def _b_pyDeriv_u(self, src, du_dm_v, adjoint=False):
        """ Derivative of b_py with wrt u

        :param SimPEG.NSEM.src src: The source of the problem
        :param numpy.ndarray du_dm_v: vector to take product with. Size (nF,) when adjoint=True, (nU,) when adjoint=False
        :param bool adjoint: adjoint?
        :rtype: numpy.ndarray
        :return: The calculated derivative, size (nU,) when adjoint=True. (nF,) when adjoint=False
        """
        # Primary does not depend on u
        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 * du_dm_v)
        return -1. / (1j * omega(src.freq)) * (C * du_dm_v)
Ejemplo n.º 10
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()
Ejemplo n.º 11
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.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)
            )

        if 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])
            elif locType == 'CCVy':
                Q = sp.hstack([Q])
            elif locType == 'CCVz':
                Q = sp.hstack([Z, Q])

            if zerosOutside:
                Q[indZeros, :] = 0

            return Q.tocsr()

        return self._getInterpolationMat(loc, locType, zerosOutside)
Ejemplo n.º 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.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()
Ejemplo n.º 13
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
Ejemplo n.º 14
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()
Ejemplo n.º 15
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)
Ejemplo n.º 16
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)