Example #1
0
 def _nodalGradStencilz(self):
     """
     Stencil for the nodal grad in the z-direction (nodes to z- edges)
     """
     if self.dim == 1 or self.dim == 2:
         return None
     else:
         Gz = kron3(ddx(self.nCz), speye(self.nNy), speye(self.nNx))
     return Gz
    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))
Example #3
0
 def _faceDivStencilz(self):
     """
     Face divergence operator in the z-direction (z-faces to cell centers)
     """
     if self.dim == 1 or self.dim == 2:
         return None
     elif self.dim == 3:
         Dz = kron3(ddx(self.nCz), speye(self.nCy), speye(self.nCx))
     return Dz
    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 _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))
 def _nodalLaplaciany(self):
     Hy = sdiag(1. / self.hy)
     if self.dim == 1:
         return None
     elif self.dim == 2:
         Hy = sp.kron(Hy, speye(self.nNx))
     elif self.dim == 3:
         Hy = kron3(speye(self.nNz), Hy, speye(self.nNx))
     return Hy.T * self._nodalGradStencily * Hy
    def _nodalLaplacianStencilz(self):
        warnings.warn('Laplacian has not been tested rigorously.')

        if self.dim == 1 or self.dim == 2:
            return None

        Dz = ddx(self.nCz)
        Lz = -Dz.T * Dz
        return kron3(Lz, speye(self.nNy), speye(self.nNx))
Example #8
0
 def _cellGradyStencil(self):
     if self.dim < 2:
         return None
     BC = ['neumann', 'neumann']  # TODO: remove this hard-coding
     n = self.vnC
     if (self.dim == 2):
         G2 = sp.kron(ddxCellGrad(n[1], BC), speye(n[0]))
     elif self.dim == 3:
         G2 = kron3(speye(n[2]), ddxCellGrad(n[1], BC), speye(n[0]))
     return G2
Example #9
0
 def _faceDivStencilx(self):
     """
     Face divergence operator in the x-direction (x-faces to cell centers)
     """
     if self.dim == 1:
         Dx = ddx(self.nCx)
     elif self.dim == 2:
         Dx = sp.kron(speye(self.nCy), ddx(self.nCx))
     elif self.dim == 3:
         Dx = kron3(speye(self.nCz), speye(self.nCy), ddx(self.nCx))
     return Dx
Example #10
0
 def _nodalGradStencily(self):
     """
     Stencil for the nodal grad in the y-direction (nodes to y-edges)
     """
     if self.dim == 1:
         return None
     elif self.dim == 2:
         Gy = sp.kron(ddx(self.nCy), speye(self.nNx))
     elif self.dim == 3:
         Gy = kron3(speye(self.nNz), ddx(self.nCy), speye(self.nNx))
     return Gy
Example #11
0
 def _aveN2Ey(self):
     """
     Averaging operator on cell nodes to y-edges
     """
     if self.dim == 1:
         return None
     elif self.dim == 2:
         aveN2Ey = sp.kron(av(self.nCy), speye(self.nNx))
     elif self.dim == 3:
         aveN2Ey = kron3(speye(self.nNz), av(self.nCy), speye(self.nNx))
     return aveN2Ey
Example #12
0
 def _aveN2Ex(self):
     """
     Averaging operator on cell nodes to x-edges
     """
     if self.dim == 1:
         aveN2Ex = av(self.nCx)
     elif self.dim == 2:
         aveN2Ex = sp.kron(speye(self.nNy), av(self.nCx))
     elif self.dim == 3:
         aveN2Ex = kron3(speye(self.nNz), speye(self.nNy), av(self.nCx))
     return aveN2Ex
Example #13
0
 def _cellGradxStencil(self):
     # TODO: remove this hard-coding
     BC = ['neumann', 'neumann']
     if self.dim == 1:
         G1 = ddxCellGrad(self.nCx, BC)
     elif self.dim == 2:
         G1 = sp.kron(speye(self.nCy), ddxCellGrad(self.nCx, BC))
     elif self.dim == 3:
         G1 = kron3(speye(self.nCz), speye(self.nCy),
                    ddxCellGrad(self.nCx, BC))
     return G1
Example #14
0
    def _nodalLaplacianStencilx(self):
        warnings.warn('Laplacian has not been tested rigorously.')

        Dx = ddx(self.nCx)
        Lx = -Dx.T * Dx

        if self.dim == 2:
            Lx = sp.kron(speye(self.nNy), Lx)
        elif self.dim == 3:
            Lx = kron3(speye(self.nNz), speye(self.nNy), Lx)
        return Lx
Example #15
0
 def _nodalGradStencilx(self):
     """
     Stencil for the nodal grad in the x-direction (nodes to x-edges)
     """
     if self.dim == 1:
         Gx = ddx(self.nCx)
     elif self.dim == 2:
         Gx = sp.kron(speye(self.nNy), ddx(self.nCx))
     elif self.dim == 3:
         Gx = kron3(speye(self.nNz), speye(self.nNy), ddx(self.nCx))
     return Gx
Example #16
0
 def _faceDivStencily(self):
     """
     Face divergence operator in the y-direction (y-faces to cell centers)
     """
     if self.dim == 1:
         return None
     elif self.dim == 2:
         Dy = sp.kron(ddx(self.nCy), speye(self.nCx))
     elif self.dim == 3:
         Dy = kron3(speye(self.nCz), ddx(self.nCy), speye(self.nCx))
     return Dy
Example #17
0
 def aveFz2CC(self):
     """
     Construct the averaging operator on cell faces in the z direction to
     cell centers.
     """
     if self.dim < 3:
         return None
     if getattr(self, '_aveFz2CC', None) is None:
         n = self.vnC
         if (self.dim == 3):
             self._aveFz2CC = kron3(av(n[2]), speye(n[1]), speye(n[0]))
     return self._aveFz2CC
Example #18
0
 def aveCCV2F(self):
     """
     Construct the averaging operator on cell centers to
     faces as a vector.
     """
     if getattr(self, '_aveCCV2F', None) is None:
         if self.dim == 1:
             self._aveCCV2F = self.aveCC2F
         elif self.dim == 2:
             aveCCV2Fx = sp.kron(speye(self.nCy), av_extrap(self.nCx))
             aveCC2VFy = sp.kron(av_extrap(self.nCy), speye(self.nCx))
             self._aveCCV2F = sp.block_diag((
                 aveCCV2Fx, aveCC2VFy
             ), format="csr")
         elif self.dim == 3:
             aveCCV2Fx = kron3(
                 speye(self.nCz), speye(self.nCy), av_extrap(self.nCx)
             )
             aveCC2VFy = kron3(
                 speye(self.nCz), av_extrap(self.nCy), speye(self.nCx)
             )
             aveCC2BFz = kron3(
                 av_extrap(self.nCz), speye(self.nCy), speye(self.nCx)
             )
             self._aveCCV2F = sp.block_diag((
                     aveCCV2Fx, aveCC2VFy, aveCC2BFz
             ), format="csr")
     return self._aveCCV2F
Example #19
0
    def _nodalLaplacianStencily(self):
        warnings.warn('Laplacian has not been tested rigorously.')

        if self.dim == 1:
            return None

        Dy = ddx(self.nCy)
        Ly = -Dy.T * Dy

        if self.dim == 2:
            Ly = sp.kron(Ly, speye(self.nNx))
        elif self.dim == 3:
            Ly = kron3(speye(self.nNz), Ly, speye(self.nNx))
        return Ly
Example #20
0
 def cellGradBC(self):
     """
     The cell centered Gradient boundary condition matrix
     """
     if getattr(self, '_cellGradBC', None) is None:
         BC = self.setCellGradBC(self._cellGradBC_list)
         n = self.vnC
         if self.dim == 1:
             G = ddxCellGradBC(n[0], BC[0])
         elif self.dim == 2:
             G1 = sp.kron(speye(n[1]), ddxCellGradBC(n[0], BC[0]))
             G2 = sp.kron(ddxCellGradBC(n[1], BC[1]), speye(n[0]))
             G = sp.block_diag((G1, G2), format="csr")
         elif self.dim == 3:
             G1 = kron3(speye(n[2]), speye(n[1]),
                        ddxCellGradBC(n[0], BC[0]))
             G2 = kron3(speye(n[2]), ddxCellGradBC(n[1], BC[1]),
                        speye(n[0]))
             G3 = kron3(ddxCellGradBC(n[2], BC[2]), speye(n[1]),
                        speye(n[0]))
             G = sp.block_diag((G1, G2, G3), format="csr")
         # Compute areas of cell faces & volumes
         S = self.area
         V = self.aveCC2F * self.vol  # Average volume between adjacent cells
         self._cellGradBC = sdiag(S / V) * G
     return self._cellGradBC
Example #21
0
 def aveEx2CC(self):
     """
     Construct the averaging operator on cell edges in the x direction to
     cell centers.
     """
     if getattr(self, '_aveEx2CC', None) is None:
         # The number of cell centers in each direction
         n = self.vnC
         if self.dim == 1:
             self._aveEx2CC = speye(n[0])
         elif self.dim == 2:
             self._aveEx2CC = sp.kron(av(n[1]), speye(n[0]))
         elif self.dim == 3:
             self._aveEx2CC = kron3(av(n[2]), av(n[1]), speye(n[0]))
     return self._aveEx2CC
Example #22
0
    def aveFx2CC(self):
        """
        Construct the averaging operator on cell faces in the x direction to
        cell centers.
        """

        if getattr(self, '_aveFx2CC', None) is None:
            n = self.vnC
            if self.dim == 1:
                self._aveFx2CC = av(n[0])
            elif self.dim == 2:
                self._aveFx2CC = sp.kron(speye(n[1]), av(n[0]))
            elif self.dim == 3:
                self._aveFx2CC = kron3(speye(n[2]), speye(n[1]), av(n[0]))
        return self._aveFx2CC
Example #23
0
 def _cellGradStencil(self):
     BC = self.setCellGradBC(self._cellGradBC_list)
     if self.dim == 1:
         G = ddxCellGrad(self.nCx, BC[0])
     elif self.dim == 2:
         G1 = sp.kron(speye(self.nCy), ddxCellGrad(self.nCx, BC[0]))
         G2 = sp.kron(ddxCellGrad(self.nCy, BC[1]), speye(self.nCx))
         G = sp.vstack((G1, G2), format="csr")
     elif self.dim == 3:
         G1 = kron3(speye(self.nCz), speye(self.nCy), ddxCellGrad(self.nCx, BC[0]))
         G2 = kron3(speye(self.nCz), ddxCellGrad(self.nCy, BC[1]), speye(self.nCx))
         G3 = kron3(ddxCellGrad(self.nCz, BC[2]), speye(self.nCy), speye(self.nCx))
         G = sp.vstack((G1, G2, G3), format="csr")
     return G
Example #24
0
 def aveEz2CC(self):
     """
     Construct the averaging operator on cell edges in the z direction to
     cell centers.
     """
     if self.dim < 3:
         return None
     if getattr(self, '_aveEz2CC', None) is None:
         # The number of cell centers in each direction
         n = self.vnC
         if (self.dim == 3):
             self._aveEz2CC = kron3(speye(n[2]), av(n[1]), av(n[0]))
     return self._aveEz2CC
Example #25
0
    def _edgeCurlStencil(self):
        assert self.dim > 1, "Edge Curl only programed for 2 or 3D."

        # Compute divergence operator on faces
        if self.dim == 2:
            n = self.vnC  # The number of cell centers in each direction

            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")
            return C

        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")

            C = sp.vstack((
                self._edgeCurlStencilx,
                self._edgeCurlStencily,
                self._edgeCurlStencilz
            ), format="csr")

            return C
Example #26
0
 def aveCC2F(self):
     "Construct the averaging operator on cell centers to faces."
     if getattr(self, '_aveCC2F', None) is None:
         if self.dim == 1:
             self._aveCC2F = av_extrap(self.nCx)
         elif self.dim == 2:
             self._aveCC2F = sp.vstack(
                 (sp.kron(speye(self.nCy), av_extrap(self.nCx)),
                  sp.kron(av_extrap(self.nCy), speye(self.nCx))),
                 format="csr")
         elif self.dim == 3:
             self._aveCC2F = sp.vstack(
                 (kron3(speye(self.nCz), speye(self.nCy), av_extrap(
                     self.nCx)),
                  kron3(speye(self.nCz), av_extrap(self.nCy), speye(
                      self.nCx)),
                  kron3(av_extrap(self.nCz), speye(self.nCy), speye(
                      self.nCx))),
                 format="csr")
     return self._aveCC2F
Example #27
0
    def getBCProjWF_simple(self, discretization='CC'):
        """The weak form boundary condition projection matrices
        when mixed boundary condition is used
        """

        if discretization is not 'CC':
            raise NotImplementedError('Boundary conditions only implemented'
                                      'for CC discretization.')

        def projBC(n):
            ij = ([0, n], [0, 1])
            vals = [0, 0]
            vals[0] = 1
            vals[1] = 1
            return sp.csr_matrix((vals, ij), shape=(n + 1, 2))

        def projDirichlet(n, bc):
            bc = checkBC(bc)
            ij = ([0, n], [0, 1])
            vals = [0, 0]
            if (bc[0] == 'dirichlet'):
                vals[0] = -1
            if (bc[1] == 'dirichlet'):
                vals[1] = 1
            return sp.csr_matrix((vals, ij), shape=(n + 1, 2))

        BC = [['dirichlet', 'dirichlet'], ['dirichlet', 'dirichlet'],
              ['dirichlet', 'dirichlet']]
        n = self.vnC
        indF = self.faceBoundaryInd

        if self.dim == 1:
            Pbc = projDirichlet(n[0], BC[0])
            B = projBC(n[0])
            indF = indF[0] | indF[1]
            Pbc = Pbc * sdiag(self.area[indF])

        elif self.dim == 2:
            Pbc1 = sp.kron(speye(n[1]), projDirichlet(n[0], BC[0]))
            Pbc2 = sp.kron(projDirichlet(n[1], BC[1]), speye(n[0]))
            Pbc = sp.block_diag((Pbc1, Pbc2), format="csr")
            B1 = sp.kron(speye(n[1]), projBC(n[0]))
            B2 = sp.kron(projBC(n[1]), speye(n[0]))
            B = sp.block_diag((B1, B2), format="csr")
            indF = np.r_[(indF[0] | indF[1]), (indF[2] | indF[3])]
            Pbc = Pbc * sdiag(self.area[indF])

        elif self.dim == 3:
            Pbc1 = kron3(speye(n[2]), speye(n[1]), projDirichlet(n[0], BC[0]))
            Pbc2 = kron3(speye(n[2]), projDirichlet(n[1], BC[1]), speye(n[0]))
            Pbc3 = kron3(projDirichlet(n[2], BC[2]), speye(n[1]), speye(n[0]))
            Pbc = sp.block_diag((Pbc1, Pbc2, Pbc3), format="csr")
            B1 = kron3(speye(n[2]), speye(n[1]), projBC(n[0]))
            B2 = kron3(speye(n[2]), projBC(n[1]), speye(n[0]))
            B3 = kron3(projBC(n[2]), speye(n[1]), speye(n[0]))
            B = sp.block_diag((B1, B2, B3), format="csr")
            indF = np.r_[(indF[0] | indF[1]), (indF[2] | indF[3]),
                         (indF[4] | indF[5])]
            Pbc = Pbc * sdiag(self.area[indF])

        return Pbc, B.T
Example #28
0
    def getBCProjWF(self, BC, discretization='CC'):
        """
        The weak form boundary condition projection matrices.

        Examples
        --------

        .. code:: python

            # Neumann in all directions
            BC = 'neumann'

            # 3D, Dirichlet in y Neumann else
            BC = ['neumann', 'dirichlet', 'neumann']

            # 3D, Neumann in x on bottom of domain, Dirichlet else
            BC = [['neumann', 'dirichlet'], 'dirichlet', 'dirichlet']
        """

        if discretization is not 'CC':
            raise NotImplementedError('Boundary conditions only implemented'
                                      'for CC discretization.')

        if isinstance(BC, string_types):
            BC = [BC for _ in self.vnC]  # Repeat the str self.dim times
        elif isinstance(BC, list):
            assert len(BC) == self.dim, 'BC list must be the size of your mesh'
        else:
            raise Exception("BC must be a str or a list.")

        for i, bc_i in enumerate(BC):
            BC[i] = checkBC(bc_i)

        def projDirichlet(n, bc):
            bc = checkBC(bc)
            ij = ([0, n], [0, 1])
            vals = [0, 0]
            if (bc[0] == 'dirichlet'):
                vals[0] = -1
            if (bc[1] == 'dirichlet'):
                vals[1] = 1
            return sp.csr_matrix((vals, ij), shape=(n + 1, 2))

        def projNeumannIn(n, bc):
            bc = checkBC(bc)
            P = sp.identity(n + 1).tocsr()
            if (bc[0] == 'neumann'):
                P = P[1:, :]
            if (bc[1] == 'neumann'):
                P = P[:-1, :]
            return P

        def projNeumannOut(n, bc):
            bc = checkBC(bc)
            ij = ([0, 1], [0, n])
            vals = [0, 0]
            if (bc[0] == 'neumann'):
                vals[0] = 1
            if (bc[1] == 'neumann'):
                vals[1] = 1
            return sp.csr_matrix((vals, ij), shape=(2, n + 1))

        n = self.vnC
        indF = self.faceBoundaryInd
        if self.dim == 1:
            Pbc = projDirichlet(n[0], BC[0])
            indF = indF[0] | indF[1]
            Pbc = Pbc * sdiag(self.area[indF])

            Pin = projNeumannIn(n[0], BC[0])

            Pout = projNeumannOut(n[0], BC[0])

        elif self.dim == 2:
            Pbc1 = sp.kron(speye(n[1]), projDirichlet(n[0], BC[0]))
            Pbc2 = sp.kron(projDirichlet(n[1], BC[1]), speye(n[0]))
            Pbc = sp.block_diag((Pbc1, Pbc2), format="csr")
            indF = np.r_[(indF[0] | indF[1]), (indF[2] | indF[3])]
            Pbc = Pbc * sdiag(self.area[indF])

            P1 = sp.kron(speye(n[1]), projNeumannIn(n[0], BC[0]))
            P2 = sp.kron(projNeumannIn(n[1], BC[1]), speye(n[0]))
            Pin = sp.block_diag((P1, P2), format="csr")

            P1 = sp.kron(speye(n[1]), projNeumannOut(n[0], BC[0]))
            P2 = sp.kron(projNeumannOut(n[1], BC[1]), speye(n[0]))
            Pout = sp.block_diag((P1, P2), format="csr")

        elif self.dim == 3:
            Pbc1 = kron3(speye(n[2]), speye(n[1]), projDirichlet(n[0], BC[0]))
            Pbc2 = kron3(speye(n[2]), projDirichlet(n[1], BC[1]), speye(n[0]))
            Pbc3 = kron3(projDirichlet(n[2], BC[2]), speye(n[1]), speye(n[0]))
            Pbc = sp.block_diag((Pbc1, Pbc2, Pbc3), format="csr")
            indF = np.r_[(indF[0] | indF[1]), (indF[2] | indF[3]),
                         (indF[4] | indF[5])]
            Pbc = Pbc * sdiag(self.area[indF])

            P1 = kron3(speye(n[2]), speye(n[1]), projNeumannIn(n[0], BC[0]))
            P2 = kron3(speye(n[2]), projNeumannIn(n[1], BC[1]), speye(n[0]))
            P3 = kron3(projNeumannIn(n[2], BC[2]), speye(n[1]), speye(n[0]))
            Pin = sp.block_diag((P1, P2, P3), format="csr")

            P1 = kron3(speye(n[2]), speye(n[1]), projNeumannOut(n[0], BC[0]))
            P2 = kron3(speye(n[2]), projNeumannOut(n[1], BC[1]), speye(n[0]))
            P3 = kron3(projNeumannOut(n[2], BC[2]), speye(n[1]), speye(n[0]))
            Pout = sp.block_diag((P1, P2, P3), format="csr")

        return Pbc, Pin, Pout
Example #29
0
 def _aveN2Fz(self):
     if self.dim == 1 or self.dim == 2:
         return None
     else:
         aveN2Fz = kron3(speye(self.nNz), av(self.nCy), av(self.nCx))
     return aveN2Fz
Example #30
0
 def _nodalLaplacianz(self):
     if self.dim == 1 or self.dim == 2:
         return None
     Hz = sdiag(1. / self.hz)
     Hz = kron3(Hz, speye(self.nNy), speye(self.nNx))
     return Hz.T * self._nodalLaplacianStencilz * Hz