Beispiel #1
0
 def func(v):
     dMdm = spzeros(n_items, inv_items)
     if tensor_type == 0:
         for P in Ps:
             dMdm = dMdm + sp.csr_matrix(
                 (P.T * (P * v), (range(n_items), np.zeros(n_items))),
                 shape=(n_items, inv_items))
     elif tensor_type == 1:
         for P in Ps:
             ys = P @ v
             dMdm = dMdm + P.T @ sp.csr_matrix(
                 (ys, col_inds, ind_ptr),
                 shape=(n_cells * dim, inv_items))
     elif tensor_type == 2:
         for P in Ps:
             ys = P @ v
             dMdm = dMdm + P.T @ sp.csr_matrix(
                 (ys, col_inds, ind_ptr),
                 shape=(n_cells * dim, inv_items))
     elif tensor_type == 3:
         for P in Ps:
             ys = P @ v
             ys = np.repeat(ys, dim).reshape((-1, dim, dim))
             ys = ys.transpose((0, 2, 1)).reshape(-1)
             dMdm = dMdm + P.T @ sp.csr_matrix(
                 (ys, col_inds, ind_ptr),
                 shape=(n_cells * dim, inv_items))
     return dMdm
Beispiel #2
0
    def _edgeCurlStencily(self):
        n = self.vnC  # The number of cell centers in each direction

        D31 = kron3(ddx(n[2]), speye(n[1] + 1), speye(n[0]))
        D13 = kron3(speye(n[2]), speye(n[1] + 1), ddx(n[0]))
        # O2 = spzeros(np.shape(D31)[0], np.shape(D32)[1])
        O2 = spzeros(n[0] * (n[1] + 1) * n[2], (n[0] + 1) * n[1] * (n[2] + 1))

        return sp.hstack((D31, O2, -D13))
Beispiel #3
0
    def _edgeCurlStencilz(self):
        n = self.vnC  # The number of cell centers in each direction

        D21 = kron3(speye(n[2] + 1), ddx(n[1]), speye(n[0]))
        D12 = kron3(speye(n[2] + 1), speye(n[1]), ddx(n[0]))
        # O3 = spzeros(np.shape(D21)[0], np.shape(D13)[1])
        O3 = spzeros(n[0] * n[1] * (n[2] + 1), (n[0] + 1) * (n[1] + 1) * n[2])

        return sp.hstack((-D21, D12, O3))
Beispiel #4
0
    def _edgeCurlStencilx(self):
        n = self.vnC  # The number of cell centers in each direction

        D32 = kron3(ddx(n[2]), speye(n[1]), speye(n[0] + 1))
        D23 = kron3(speye(n[2]), ddx(n[1]), speye(n[0] + 1))
        # O1 = spzeros(np.shape(D32)[0], np.shape(D31)[1])
        O1 = spzeros((n[0] + 1) * n[1] * n[2], n[0] * (n[1] + 1) * (n[2] + 1))

        return sp.hstack((O1, -D32, D23))
    def _getInnerProductDerivFunction(self, tensorType, P, projType, v):
        """
        :param numpy.ndarray prop: material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))
        :param numpy.ndarray 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
Beispiel #6
0
    def _getInterpolationMat(
        self, loc, location_type="cell_centers", zeros_outside=False
    ):
        """Produces interpolation matrix

        Parameters
        ----------
        loc : numpy.ndarray
            Location of points to interpolate to

        location_type: str, optional
            What to interpolate

            location_type can be::

                'Ex', 'edges_x'           -> x-component of field defined on x edges
                'Ey', 'edges_y'           -> y-component of field defined on y edges
                'Ez', 'edges_z'           -> z-component of field defined on z edges
                'Fx', 'faces_x'           -> x-component of field defined on x faces
                'Fy', 'faces_y'           -> y-component of field defined on y faces
                'Fz', 'faces_z'           -> z-component of field defined on z faces
                'N', 'nodes'              -> scalar field defined on nodes
                'CC', 'cell_centers'      -> scalar field defined on cell centers
                'CCVx', 'cell_centers_x'  -> x-component of vector field defined on cell centers
                'CCVy', 'cell_centers_y'  -> y-component of vector field defined on cell centers
                'CCVz', 'cell_centers_z'  -> z-component of vector field defined on cell centers

        Returns
        -------
        scipy.sparse.csr_matrix
            M, the interpolation matrix

        """

        loc = as_array_n_by_dim(loc, self.dim)

        if not zeros_outside:
            if not np.all(self.is_inside(loc)):
                raise ValueError("Points outside of mesh")
        else:
            indZeros = np.logical_not(self.is_inside(loc))
            loc[indZeros, :] = np.array([v.mean() for v in self.get_tensor("CC")])

        location_type = self._parse_location_type(location_type)

        if location_type in [
            "faces_x",
            "faces_y",
            "faces_z",
            "edges_x",
            "edges_y",
            "edges_z",
        ]:
            ind = {"x": 0, "y": 1, "z": 2}[location_type[-1]]
            if self.dim < ind:
                raise ValueError("mesh is not high enough dimension.")
            if "f" in location_type.lower():
                items = (self.nFx, self.nFy, self.nFz)[: self.dim]
            else:
                items = (self.nEx, self.nEy, self.nEz)[: self.dim]
            components = [spzeros(loc.shape[0], n) for n in items]
            components[ind] = interpolation_matrix(loc, *self.get_tensor(location_type))
            # remove any zero blocks (hstack complains)
            components = [comp for comp in components if comp.shape[1] > 0]
            Q = sp.hstack(components)

        elif location_type in ["cell_centers", "nodes"]:
            Q = interpolation_matrix(loc, *self.get_tensor(location_type))

        elif location_type in ["cell_centers_x", "cell_centers_y", "cell_centers_z"]:
            Q = interpolation_matrix(loc, *self.get_tensor("CC"))
            Z = spzeros(loc.shape[0], self.nC)
            if location_type[-1] == "x":
                Q = sp.hstack([Q, Z, Z])
            elif location_type[-1] == "y":
                Q = sp.hstack([Z, Q, Z])
            elif location_type[-1] == "z":
                Q = sp.hstack([Z, Z, Q])

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

        if zeros_outside:
            Q[indZeros, :] = 0

        return Q.tocsr()
    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
        """

        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()
Beispiel #8
0
    def _getInnerProductDerivFunction(self, tensorType, P, projection_type, v):
        """
        Parameters
        ----------
        model : numpy.ndarray
            material property (tensor properties are possible) at each cell center (nC, (1, 3, or 6))

        v : numpy.ndarray
            vector to multiply (required in the general implementation)

        P : list
            list of projection matrices

        projection_type : str
            'F' for faces 'E' for edges


        Returns
        -------
        scipy.sparse.csr_matrix
            dMdm, the derivative of the inner product matrix (n, nC*nA)

        """
        if projection_type not in ["F", "E"]:
            raise TypeError(
                "projection_type must be 'F' for faces or 'E' for edges")

        n = getattr(self, "n" + projection_type)

        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