예제 #1
0
 def _getEdgeP(self, edge0, edge1, edge2):
     I, J, V = [], [], []
     for cell in self.sortedCells:
         if self.dim == 2:
             e2f = lambda e: ('f' + {'X':'Y','Y':'X'}[e[1]]
                                  + {'0':'m','1':'p'}[e[2]])
             face = cell.faceDict[e2f(edge0)]
             if face.isleaf:
                 j = face.index
             else:
                 j = face.children[0 if 'm' in e2f(edge1) else 1].index
             # Need to flip the numbering for edges
             if 'X' in edge0:
                 j = [jj - self.nFx for jj in j]
             elif 'Y' in edge0:
                 j = [jj + self.nFy for jj in j]
         elif self.dim == 3:
             edge = cell.edgeDict[edge0]
             if edge.isleaf:
                 j = edge.index
             else:
                 mSide = lambda e: {'0':True,'1':True,'2':False,'3':False}[e[2]]
                 j = edge.children[0 if mSide(edge1) else 1,
                                   0 if mSide(edge2) else 1].index
         lenj = len(j)
         I += [cell.num]*lenj
         J += j
         V += [1./lenj]*lenj
     return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nE))
예제 #2
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:
            MI = self._fastInnerProduct(projType, prop, invProp=invProp, invMat=invMat)

        if tensorType == 0:
            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 = self.dim * Av.T * V * ones
            elif invMat and invProp:
                dMdprop =  self.dim * Utils.sdiag(MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag(1./prop**2)

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

        if tensorType == 2: # anisotropic
            Av = getattr(self, 'ave'+projType+'2CCV')
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))
            if not invMat and not invProp:
                dMdprop = Av.T * V
            elif invMat and invProp:
                dMdprop =  Utils.sdiag(MI.diagonal()**2) * Av.T * V * Utils.sdiag(1./prop**2)

        if dMdprop is not None:
            def innerProductDeriv(v=None):
                if v is None:
                    print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop'
                    return dMdprop
                return Utils.sdiag(v) * dMdprop
            return innerProductDeriv
        else:
            return None
예제 #3
0
 def _getFaceP(self, face0, face1, face2):
     I, J, V = [], [], []
     for cell in self.sortedCells:
         face = cell.faceDict[face0]
         if face.isleaf:
             j = face.index
         elif self.dim == 2:
             j = face.children[0 if 'm' in face1 else 1].index
         elif self.dim == 3:
             j = face.children[0 if 'm' in face1 else 1,
                               0 if 'm' in face2 else 1].index
         lenj = len(j)
         I += [cell.num]*lenj
         J += j
         V += [1./lenj]*lenj
     return sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF))
예제 #4
0
 def faceDiv(self):
     if getattr(self, '_faceDiv', None) is None:
         self.number()
         # TODO: Preallocate!
         I, J, V = [], [], []
         for cell in self.sortedCells:
             faces = cell.faceDict
             for face in faces:
                 j = faces[face].index
                 I += [cell.num]*len(j)
                 J += j
                 V += [-1 if 'm' in face else 1]*len(j)
         VOL = self.vol
         D = sp.csr_matrix((V,(I,J)), shape=(self.nC, self.nF))
         S = self.area
         self._faceDiv = Utils.sdiag(1/VOL)*D*Utils.sdiag(S)
     return self._faceDiv
예제 #5
0
    def edgeCurl(self):
        """Construct the 3D curl operator."""
        assert self.dim > 2, "Edge Curl only programed for 3D."

        if getattr(self, '_edgeCurl', None) is None:
            self.number()
            # TODO: Preallocate!
            I, J, V = [], [], []
            for face in self.faces:
                for ii, edge in enumerate([face.edge0, face.edge1, face.edge2, face.edge3]):
                    j = edge.index
                    I += [face.num]*len(j)
                    J += j
                    isNeg = [True, False, True, False]
                    V += [-1 if isNeg[ii] else 1]*len(j)
            C = sp.csr_matrix((V,(I,J)), shape=(self.nF, self.nE))
            S = self.area
            L = self.edge
            self._edgeCurl = Utils.sdiag(1/S)*C*Utils.sdiag(L)
        return self._edgeCurl
예제 #6
0
 def nodalGrad(self):
     if getattr(self, '_nodalGrad', None) is None:
         self.number()
         # TODO: Preallocate!
         I, J, V = [], [], []
         # kinda a hack for the 2D gradient
         # because edges are not stored
         edges = self.faces if self.dim == 2 else self.edges
         for edge in edges:
             if self.dim == 3:
                 I += [edge.num, edge.num]
             elif self.dim == 2 and edge.faceType == 'x':
                 I += [edge.num + self.nFy, edge.num + self.nFy]
             elif self.dim == 2 and edge.faceType == 'y':
                 I += [edge.num - self.nFx, edge.num - self.nFx]
             J += [edge.node0.num, edge.node1.num]
             V += [-1, 1]
         G = sp.csr_matrix((V,(I,J)), shape=(self.nE, self.nN))
         L = self.edge
         self._nodalGrad = Utils.sdiag(1/L)*G
     return self._nodalGrad
예제 #7
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:
            MI = self._fastInnerProduct(projType,
                                        prop,
                                        invProp=invProp,
                                        invMat=invMat)

        if tensorType == 0:
            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 = self.dim * Av.T * V * ones
            elif invMat and invProp:
                dMdprop = self.dim * Utils.sdiag(
                    MI.diagonal()**2) * Av.T * V * ones * Utils.sdiag(
                        1. / prop**2)

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

        if tensorType == 2:  # anisotropic
            Av = getattr(self, 'ave' + projType + '2CCV')
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))
            if not invMat and not invProp:
                dMdprop = Av.T * V
            elif invMat and invProp:
                dMdprop = Utils.sdiag(MI.diagonal()**
                                      2) * Av.T * V * Utils.sdiag(1. / prop**2)

        if dMdprop is not None:

            def innerProductDeriv(v=None):
                if v is None:
                    print 'Depreciation Warning: TensorMesh.innerProductDeriv. You should be supplying a vector. Use: sdiag(u)*dMdprop'
                    return dMdprop
                return Utils.sdiag(v) * dMdprop

            return innerProductDeriv
        else:
            return None
예제 #8
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
예제 #9
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