Пример #1
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

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

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

        if invProp:
            prop = 1./prop

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

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

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

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

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

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

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Пример #2
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

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

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

        if invProp:
            prop = 1.0 / prop

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

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

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

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

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

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

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Пример #3
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi * x[:, 0]) * np.cos(np.pi * x[:, 1])
        j_funX = lambda x: -np.pi * np.sin(np.pi * x[:, 0]) * np.cos(np.pi *
                                                                     x[:, 1])
        j_funY = lambda x: -np.pi * np.cos(np.pi * x[:, 0]) * np.sin(np.pi *
                                                                     x[:, 1])
        q_fun = lambda x: -2 * (np.pi**2) * phi(x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana, jY_ana]

        #TODO: Check where our boundary conditions are CCx or Nx
        # fxm,fxp,fym,fyp = self.M.faceBoundaryInd
        # gBFx = self.M.gridFx[(fxm|fxp),:]
        # gBFy = self.M.gridFy[(fym|fyp),:]
        fxm, fxp, fym, fyp = self.M.cellBoundaryInd
        gBFx = self.M.gridCC[(fxm | fxp), :]
        gBFy = self.M.gridCC[(fym | fyp), :]

        bc = phi(np.r_[gBFx, gBFy])

        # P = sp.csr_matrix(([-1,1],([0,self.M.nF-1],[0,1])), shape=(self.M.nF, 2))

        P, Pin, Pout = self.M.getBCProjWF('dirichlet')

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        G = -self.M.faceDiv.T * Utils.sdiag(self.M.vol)
        D = self.M.faceDiv
        j = McI * (G * xc_ana + P * bc)
        q = D * j

        # self.M.plotImage(j, 'FxFy', showIt=True)

        # Rearrange if we know q to solve for x
        A = D * McI * G
        rhs = q_ana - D * McI * P * bc

        if self.myTest == 'j':
            err = np.linalg.norm((j - j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q - q_ana), np.inf)
        elif self.myTest == 'xc':
            xc = Solver(A) * (rhs)
            err = np.linalg.norm((xc - xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            xc = Solver(A) * (rhs)
            j = McI * (G * xc + P * bc)
            err = np.linalg.norm((j - j_ana), np.inf)

        return err
Пример #4
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(0.5*np.pi*x)
        j_fun = lambda x: -0.5*np.pi*np.sin(0.5*np.pi*x)
        q_fun = lambda x: -0.25*(np.pi**2)*np.cos(0.5*np.pi*x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        vecN = self.M.vectorNx
        vecC = self.M.vectorCCx

        phi_bc = phi(vecC[[0,-1]])
        j_bc = j_fun(vecN[[0,-1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'neumann']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T*Pin*self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*phi_bc)
        q = V*D*Pin.T*Pin*j + V*D*Pout.T*j_bc

        # Rearrange if we know q to solve for x
        A = V*D*Pin.T*Pin*McI*G
        rhs = V*q_ana - V*D*Pin.T*Pin*McI*P*phi_bc - V*D*Pout.T*j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc


        if self.myTest == 'j':
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-V*q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            err = np.linalg.norm((xc-xc_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            j = McI*(G*xc + P*phi_bc)
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        return err
Пример #5
0
 def DCfun(mesh, pts):
     D = mesh.faceDiv
     G = D.T
     sigma = 1e-2*np.ones(mesh.nC)
     Msigi = mesh.getFaceInnerProduct(1./sigma)
     MsigI = Utils.sdInv(Msigi)
     A = D*MsigI*G
     A[-1,-1] /= mesh.vol[-1] # Remove null space
     rhs = np.zeros(mesh.nC)
     txind = Utils.meshutils.closestPoints(mesh, pts)
     rhs[txind] = np.r_[1,-1]
     return A, rhs
 def DCfun(mesh, pts):
     D = mesh.faceDiv
     G = D.T
     sigma = 1e-2 * np.ones(mesh.nC)
     Msigi = mesh.getFaceInnerProduct(1. / sigma)
     MsigI = Utils.sdInv(Msigi)
     A = D * MsigI * G
     A[-1, -1] /= mesh.vol[-1]  # Remove null space
     rhs = np.zeros(mesh.nC)
     txind = Utils.meshutils.closestPoints(mesh, pts)
     rhs[txind] = np.r_[1, -1]
     return A, rhs
Пример #7
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(0.5 * np.pi * x)
        j_fun = lambda x: -0.5 * np.pi * np.sin(0.5 * np.pi * x)
        q_fun = lambda x: -0.25 * (np.pi**2) * np.cos(0.5 * np.pi * x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        vecN = self.M.vectorNx
        vecC = self.M.vectorCCx

        phi_bc = phi(vecC[[0, -1]])
        j_bc = j_fun(vecN[[0, -1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'neumann']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T * Pin * self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI * (G * xc_ana + P * phi_bc)
        q = V * D * Pin.T * Pin * j + V * D * Pout.T * j_bc

        # Rearrange if we know q to solve for x
        A = V * D * Pin.T * Pin * McI * G
        rhs = V * q_ana - V * D * Pin.T * Pin * McI * P * phi_bc - V * D * Pout.T * j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc

        if self.myTest == 'j':
            err = np.linalg.norm((Pin * j - Pin * j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q - V * q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol=1e-6)
            err = np.linalg.norm((xc - xc_ana), np.inf)
            if info > 0:
                print 'Solve does not work well'
                print 'ACCURACY', np.linalg.norm(Utils.mkvc(A * xc) - rhs)
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol=1e-6)
            j = McI * (G * xc + P * phi_bc)
            err = np.linalg.norm((Pin * j - Pin * j_ana), np.inf)
            if info > 0:
                print 'Solve does not work well'
                print 'ACCURACY', np.linalg.norm(Utils.mkvc(A * xc) - rhs)
        return err
Пример #8
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi*x[:,0])*np.cos(np.pi*x[:,1])
        j_funX = lambda x: -np.pi*np.sin(np.pi*x[:,0])*np.cos(np.pi*x[:,1])
        j_funY = lambda x: -np.pi*np.cos(np.pi*x[:,0])*np.sin(np.pi*x[:,1])
        q_fun = lambda x: -2*(np.pi**2)*phi(x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana,jY_ana]

        #TODO: Check where our boundary conditions are CCx or Nx
        # fxm,fxp,fym,fyp = self.M.faceBoundaryInd
        # gBFx = self.M.gridFx[(fxm|fxp),:]
        # gBFy = self.M.gridFy[(fym|fyp),:]
        fxm,fxp,fym,fyp = self.M.cellBoundaryInd
        gBFx = self.M.gridCC[(fxm|fxp),:]
        gBFy = self.M.gridCC[(fym|fyp),:]

        bc = phi(np.r_[gBFx,gBFy])

        # P = sp.csr_matrix(([-1,1],([0,self.M.nF-1],[0,1])), shape=(self.M.nF, 2))

        P, Pin, Pout = self.M.getBCProjWF('dirichlet')

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        G = -self.M.faceDiv.T * Utils.sdiag(self.M.vol)
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*bc)
        q = D*j

        # self.M.plotImage(j, 'FxFy', showIt=True)

        # Rearrange if we know q to solve for x
        A = D*McI*G
        rhs = q_ana - D*McI*P*bc

        if self.myTest == 'j':
            err = np.linalg.norm((j-j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-q_ana), np.inf)
        elif self.myTest == 'xc':
            xc = Solver(A) * (rhs)
            err = np.linalg.norm((xc-xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            xc = Solver(A) * (rhs)
            j = McI*(G*xc + P*bc)
            err = np.linalg.norm((j-j_ana), np.inf)

        return err
Пример #9
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi*x)
        j_fun = lambda x: -np.pi*np.sin(np.pi*x)
        q_fun = lambda x: -(np.pi**2)*np.cos(np.pi*x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        # vec = self.M.vectorNx
        vec = self.M.vectorCCx

        phi_bc = phi(vec[[0,-1]])
        j_bc = j_fun(vec[[0,-1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'dirichlet']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T*Pin*self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*phi_bc)
        q = V*D*Pin.T*Pin*j + V*D*Pout.T*j_bc

        # Rearrange if we know q to solve for x
        A = V*D*Pin.T*Pin*McI*G
        rhs = V*q_ana - V*D*Pin.T*Pin*McI*P*phi_bc - V*D*Pout.T*j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc


        if self.myTest == 'j':
            err = np.linalg.norm((j-j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-V*q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            solver = SolverCG(A, maxiter=1000)
            xc = solver * (rhs)
            print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
            err = np.linalg.norm((xc-xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc = Solver(A) * (rhs)
            print(np.linalg.norm(Utils.mkvc(A*xc) - rhs))
            j = McI*(G*xc + P*phi_bc)
            err = np.linalg.norm((j-j_ana), np.inf)

        return err
Пример #10
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(np.pi * x)
        j_fun = lambda x: -np.pi * np.sin(np.pi * x)
        q_fun = lambda x: -(np.pi**2) * np.cos(np.pi * x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        j_ana = j_fun(self.M.gridFx)

        #TODO: Check where our boundary conditions are CCx or Nx
        # vec = self.M.vectorNx
        vec = self.M.vectorCCx

        phi_bc = phi(vec[[0, -1]])
        j_bc = j_fun(vec[[0, -1]])

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'dirichlet']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T * Pin * self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI * (G * xc_ana + P * phi_bc)
        q = V * D * Pin.T * Pin * j + V * D * Pout.T * j_bc

        # Rearrange if we know q to solve for x
        A = V * D * Pin.T * Pin * McI * G
        rhs = V * q_ana - V * D * Pin.T * Pin * McI * P * phi_bc - V * D * Pout.T * j_bc
        # A = D*McI*G
        # rhs = q_ana - D*McI*P*phi_bc

        if self.myTest == 'j':
            err = np.linalg.norm((j - j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q - V * q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            solver = SolverCG(A, maxiter=1000)
            xc = solver * (rhs)
            print 'ACCURACY', np.linalg.norm(Utils.mkvc(A * xc) - rhs)
            err = np.linalg.norm((xc - xc_ana), np.inf)
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc = Solver(A) * (rhs)
            print np.linalg.norm(Utils.mkvc(A * xc) - rhs)
            j = McI * (G * xc + P * phi_bc)
            err = np.linalg.norm((j - j_ana), np.inf)

        return err
Пример #11
0
    def _fastInnerProduct(self,
                          projType,
                          prop=None,
                          invProp=False,
                          invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

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

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

        if invProp:
            prop = 1. / prop

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

        if prop.size == self.nC:
            Av = getattr(self, 'ave' + projType + '2CC')
            Vprop = self.vol * Utils.mkvc(prop)
            M = self.dim * Utils.sdiag(Av.T * Vprop)
        elif prop.size == self.nC * self.dim:
            Av = getattr(self, 'ave' + projType + '2CCV')
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))
            M = Utils.sdiag(Av.T * V * Utils.mkvc(prop))
        else:
            return None

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Пример #12
0
    def _fastInnerProduct(self, projType, prop=None, invProp=False, invMat=False):
        """
            Fast version of getFaceInnerProduct.
            This does not handle the case of a full tensor prop.

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

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

        if invProp:
            prop = 1./prop

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

        if prop.size == self.nC:
            Av = getattr(self, 'ave'+projType+'2CC')
            Vprop = self.vol * Utils.mkvc(prop)
            M = self.dim * Utils.sdiag(Av.T * Vprop)
        elif prop.size == self.nC*self.dim:
            Av = getattr(self, 'ave'+projType+'2CCV')
            V = sp.kron(sp.identity(self.dim), Utils.sdiag(self.vol))
            M = Utils.sdiag(Av.T * V * Utils.mkvc(prop))
        else:
            return None

        if invMat:
            return Utils.sdInv(M)
        else:
            return M
Пример #13
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(0.5 * np.pi * x[:, 0]) * np.cos(0.5 * np.pi *
                                                               x[:, 1])
        j_funX = lambda x: -0.5 * np.pi * np.sin(
            0.5 * np.pi * x[:, 0]) * np.cos(0.5 * np.pi * x[:, 1])
        j_funY = lambda x: -0.5 * np.pi * np.cos(
            0.5 * np.pi * x[:, 0]) * np.sin(0.5 * np.pi * x[:, 1])
        q_fun = lambda x: -2 * ((0.5 * np.pi)**2) * phi(x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana, jY_ana]

        #TODO: Check where our boundary conditions are CCx or Nx

        cxm, cxp, cym, cyp = self.M.cellBoundaryInd
        fxm, fxp, fym, fyp = self.M.faceBoundaryInd

        gBFx = self.M.gridFx[(fxm | fxp), :]
        gBFy = self.M.gridFy[(fym | fyp), :]

        gBCx = self.M.gridCC[(cxm | cxp), :]
        gBCy = self.M.gridCC[(cym | cyp), :]

        phi_bc = phi(np.r_[gBCx, gBCy])
        j_bc = np.r_[j_funX(gBFx), j_funY(gBFy)]

        # P = sp.csr_matrix(([-1,1],([0,self.M.nF-1],[0,1])), shape=(self.M.nF, 2))

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'neumann'],
                                           ['dirichlet', 'neumann']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T * Pin * self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI * (G * xc_ana + P * phi_bc)
        q = V * D * Pin.T * Pin * j + V * D * Pout.T * j_bc

        # Rearrange if we know q to solve for x
        A = V * D * Pin.T * Pin * McI * G
        rhs = V * q_ana - V * D * Pin.T * Pin * McI * P * phi_bc - V * D * Pout.T * j_bc

        if self.myTest == 'j':
            err = np.linalg.norm((Pin * j - Pin * j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q - V * q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol=1e-6)
            err = np.linalg.norm((xc - xc_ana), np.inf)
            if info > 0:
                print 'Solve does not work well'
                print 'ACCURACY', np.linalg.norm(Utils.mkvc(A * xc) - rhs)
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol=1e-6)
            j = McI * (G * xc + P * phi_bc)
            err = np.linalg.norm((Pin * j - Pin * j_ana), np.inf)
            if info > 0:
                print 'Solve does not work well'
                print 'ACCURACY', np.linalg.norm(Utils.mkvc(A * xc) - rhs)
        return err
Пример #14
0
    def getError(self):
        #Test function
        phi = lambda x: np.cos(0.5*np.pi*x[:,0])*np.cos(0.5*np.pi*x[:,1])
        j_funX = lambda x: -0.5*np.pi*np.sin(0.5*np.pi*x[:,0])*np.cos(0.5*np.pi*x[:,1])
        j_funY = lambda x: -0.5*np.pi*np.cos(0.5*np.pi*x[:,0])*np.sin(0.5*np.pi*x[:,1])
        q_fun = lambda x: -2*((0.5*np.pi)**2)*phi(x)

        xc_ana = phi(self.M.gridCC)
        q_ana = q_fun(self.M.gridCC)
        jX_ana = j_funX(self.M.gridFx)
        jY_ana = j_funY(self.M.gridFy)
        j_ana = np.r_[jX_ana,jY_ana]

        #TODO: Check where our boundary conditions are CCx or Nx

        cxm,cxp,cym,cyp = self.M.cellBoundaryInd
        fxm,fxp,fym,fyp = self.M.faceBoundaryInd

        gBFx = self.M.gridFx[(fxm|fxp),:]
        gBFy = self.M.gridFy[(fym|fyp),:]

        gBCx = self.M.gridCC[(cxm|cxp),:]
        gBCy = self.M.gridCC[(cym|cyp),:]

        phi_bc = phi(np.r_[gBCx,gBCy])
        j_bc = np.r_[j_funX(gBFx), j_funY(gBFy)]

        # P = sp.csr_matrix(([-1,1],([0,self.M.nF-1],[0,1])), shape=(self.M.nF, 2))

        P, Pin, Pout = self.M.getBCProjWF([['dirichlet', 'neumann'], ['dirichlet', 'neumann']])

        Mc = self.M.getFaceInnerProduct()
        McI = Utils.sdInv(self.M.getFaceInnerProduct())
        V = Utils.sdiag(self.M.vol)
        G = -Pin.T*Pin*self.M.faceDiv.T * V
        D = self.M.faceDiv
        j = McI*(G*xc_ana + P*phi_bc)
        q = V*D*Pin.T*Pin*j + V*D*Pout.T*j_bc

        # Rearrange if we know q to solve for x
        A = V*D*Pin.T*Pin*McI*G
        rhs = V*q_ana - V*D*Pin.T*Pin*McI*P*phi_bc - V*D*Pout.T*j_bc

        if self.myTest == 'j':
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
        elif self.myTest == 'q':
            err = np.linalg.norm((q-V*q_ana), np.inf)
        elif self.myTest == 'xc':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            err = np.linalg.norm((xc-xc_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        elif self.myTest == 'xcJ':
            #TODO: fix the null space
            xc, info = sp.linalg.minres(A, rhs, tol = 1e-6)
            j = McI*(G*xc + P*phi_bc)
            err = np.linalg.norm((Pin*j-Pin*j_ana), np.inf)
            if info > 0:
                print('Solve does not work well')
                print('ACCURACY', np.linalg.norm(Utils.mkvc(A*xc) - rhs))
        return err