Beispiel #1
0
    def getInterpolationMatCartMesh(self, Mrect, locType='CC'):
        """
            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 locType == 'F':
            # do this three times for each component
            X = self.getInterpolationMatCartMesh(Mrect, locType='Fx')
            Y = self.getInterpolationMatCartMesh(Mrect, locType='Fy')
            Z = self.getInterpolationMatCartMesh(Mrect, locType='Fz')
            return sp.vstack((X, Y, Z))
        if locType == 'E':
            X = self.getInterpolationMatCartMesh(Mrect, locType='Ex')
            Y = self.getInterpolationMatCartMesh(Mrect, locType='Ey')
            Z = spzeros(Mrect.nEz, self.nE)
            return sp.vstack((X, Y, Z))

        grid = getattr(Mrect, 'grid' + locType)
        # 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:, :],
            }[locType]
            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 = sdiag(proj)
        return Proj * Pc2r
Beispiel #2
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 = 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 = sdiag(proj)
        return Proj * Pc2r
Beispiel #3
0
        def fget(self):
            if(self._edgeCurl is None):
                assert self.dim > 1, "Edge Curl only programed for 2 or 3D."
                # The number of cell centers in each direction
                n = self.vnC

                # Compute lengths of cell edges
                L = self.edge

                # Compute areas of cell faces
                S = self.area

                # Compute divergence operator on faces
                if self.dim == 2:

                    D21 = sp.kron(ddx(n[1]), speye(n[0]))
                    D12 = sp.kron(speye(n[1]), ddx(n[0]))
                    C = sp.hstack((-D21, D12), format="csr")
                    self._edgeCurl = C*sdiag(1/S)

                elif self.dim == 3:

                    D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0]+1))
                    D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0]+1))
                    D31 = kron3(ddx(n[2]), speye(n[1]+1), speye(n[0]))
                    D13 = kron3(speye(n[2]), speye(n[1]+1), ddx(n[0]))
                    D21 = kron3(speye(n[2]+1), ddx(n[1]), speye(n[0]))
                    D12 = kron3(speye(n[2]+1), speye(n[1]), ddx(n[0]))

                    O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1])
                    O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1])
                    O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1])

                    C = sp.vstack((sp.hstack((O1, -D32, D23)),
                                   sp.hstack((D31, O2, -D13)),
                                   sp.hstack((-D21, D12, O3))), format="csr")

                    self._edgeCurl = sdiag(1/S)*(C*sdiag(L))

            return self._edgeCurl
Beispiel #4
0
        def fget(self):
            if(self._edgeCurl is None):
                assert self.dim > 1, "Edge Curl only programed for 2 or 3D."
                # The number of cell centers in each direction
                n = self.vnC

                # Compute lengths of cell edges
                L = self.edge

                # Compute areas of cell faces
                S = self.area

                # Compute divergence operator on faces
                if self.dim == 2:

                    D21 = sp.kron(ddx(n[1]), speye(n[0]))
                    D12 = sp.kron(speye(n[1]), ddx(n[0]))
                    C = sp.hstack((-D21, D12), format="csr")
                    self._edgeCurl = C*sdiag(1/S)

                elif self.dim == 3:

                    D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0]+1))
                    D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0]+1))
                    D31 = kron3(ddx(n[2]), speye(n[1]+1), speye(n[0]))
                    D13 = kron3(speye(n[2]), speye(n[1]+1), ddx(n[0]))
                    D21 = kron3(speye(n[2]+1), ddx(n[1]), speye(n[0]))
                    D12 = kron3(speye(n[2]+1), speye(n[1]), ddx(n[0]))

                    O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1])
                    O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1])
                    O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1])

                    C = sp.vstack((sp.hstack((O1, -D32, D23)),
                                   sp.hstack((D31, O2, -D13)),
                                   sp.hstack((-D21, D12, O3))), format="csr")

                    self._edgeCurl = sdiag(1/S)*(C*sdiag(L))

            return self._edgeCurl
Beispiel #5
0
    def _getInnerProductDerivFunction(self, tensorType, P, projType, v):
        """
            :param numpy.array prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))
            :param numpy.array v: vector to multiply (required in the general implementation)
            :param list P: list of projection matrices
            :param str projType: 'F' for faces 'E' for edges
            :rtype: scipy.sparse.csr_matrix
            :return: dMdm, the derivative of the inner product matrix (n, nC*nA)
        """
        assert projType in [
            'F', 'E'
        ], "projType must be 'F' for faces or 'E' for edges"
        n = getattr(self, 'n' + projType)

        if tensorType == -1:
            return None

        if v is None:
            raise Exception('v must be supplied for this implementation.')

        d = self.dim
        Z = spzeros(self.nC, self.nC)

        if tensorType == 0:
            dMdm = spzeros(n, 1)
            for i, p in enumerate(P):
                dMdm = dMdm + sp.csr_matrix(
                    (p.T * (p * v), (range(n), np.zeros(n))), shape=(n, 1))
        if d == 1:
            if tensorType == 1:
                dMdm = spzeros(n, self.nC)
                for i, p in enumerate(P):
                    dMdm = dMdm + p.T * sdiag(p * v)
        elif d == 2:
            if tensorType == 1:
                dMdm = spzeros(n, self.nC)
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:]
                    dMdm = dMdm + p.T * sp.vstack((sdiag(y1), sdiag(y2)))
            elif tensorType == 2:
                dMdms = [spzeros(n, self.nC) for _ in range(2)]
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:]
                    dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z))
                    dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2)))
                dMdm = sp.hstack(dMdms)
            elif tensorType == 3:
                dMdms = [spzeros(n, self.nC) for _ in range(3)]
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:]
                    dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z))
                    dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2)))
                    dMdms[2] = dMdms[2] + p.T * sp.vstack(
                        (sdiag(y2), sdiag(y1)))
                dMdm = sp.hstack(dMdms)
        elif d == 3:
            if tensorType == 1:
                dMdm = spzeros(n, self.nC)
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:self.nC * 2]
                    y3 = Y[self.nC * 2:]
                    dMdm = dMdm + p.T * sp.vstack(
                        (sdiag(y1), sdiag(y2), sdiag(y3)))
            elif tensorType == 2:
                dMdms = [spzeros(n, self.nC) for _ in range(3)]
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:self.nC * 2]
                    y3 = Y[self.nC * 2:]
                    dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z))
                    dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z))
                    dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3)))
                dMdm = sp.hstack(dMdms)
            elif tensorType == 3:
                dMdms = [spzeros(n, self.nC) for _ in range(6)]
                for i, p in enumerate(P):
                    Y = p * v
                    y1 = Y[:self.nC]
                    y2 = Y[self.nC:self.nC * 2]
                    y3 = Y[self.nC * 2:]
                    dMdms[0] = dMdms[0] + p.T * sp.vstack((sdiag(y1), Z, Z))
                    dMdms[1] = dMdms[1] + p.T * sp.vstack((Z, sdiag(y2), Z))
                    dMdms[2] = dMdms[2] + p.T * sp.vstack((Z, Z, sdiag(y3)))
                    dMdms[3] = dMdms[3] + p.T * sp.vstack(
                        (sdiag(y2), sdiag(y1), Z))
                    dMdms[4] = dMdms[4] + p.T * sp.vstack(
                        (sdiag(y3), Z, sdiag(y1)))
                    dMdms[5] = dMdms[5] + p.T * sp.vstack(
                        (Z, sdiag(y3), sdiag(y2)))
                dMdm = sp.hstack(dMdms)

        return dMdm