Esempio n. 1
0
 def computeMatrixKorn(self, mucell):
     ncomp = self.ncomp
     dimension, dV, ndofs = self.mesh.dimension, self.mesh.dV, self.nunknowns(
     )
     nloc, dofspercell, nall = self.nlocal(), self.dofspercell(
     ), ncomp * ndofs
     ci0 = self.mesh.cellsOfInteriorFaces[:, 0]
     ci1 = self.mesh.cellsOfInteriorFaces[:, 1]
     assert np.all(ci1 >= 0)
     normalsS = self.mesh.normals[self.mesh.innerfaces]
     dS = linalg.norm(normalsS, axis=1)
     faces = self.mesh.faces[self.mesh.innerfaces]
     # fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(faces, ci0, ci1)
     fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(ci0, ci1)
     massloc = barycentric.crbdryothers(dimension)
     if isinstance(mucell, (int, float)):
         scale = mucell * dS / (dV[ci0] + dV[ci1])
     else:
         scale = (mucell[ci0] + mucell[ci1]) * dS / (dV[ci0] + dV[ci1])
     scale *= 8
     A = sparse.coo_matrix((nall, nall))
     mat = np.einsum('n,kl->nkl', dS * scale, massloc).reshape(-1)
     for icomp in range(ncomp):
         d0 = ncomp * fi0 + icomp
         d1 = ncomp * fi1 + icomp
         rows0 = d0.repeat(nloc - 1)
         cols0 = np.tile(d0, nloc - 1).ravel()
         rows1 = d1.repeat(nloc - 1)
         cols1 = np.tile(d1, nloc - 1).ravel()
         A += sparse.coo_matrix((mat, (rows0, cols0)), shape=(nall, nall))
         A += sparse.coo_matrix((-mat, (rows0, cols1)), shape=(nall, nall))
         A += sparse.coo_matrix((-mat, (rows1, cols0)), shape=(nall, nall))
         A += sparse.coo_matrix((mat, (rows1, cols1)), shape=(nall, nall))
     return A
Esempio n. 2
0
    def computeBdryMassMatrix(self, colors=None, coeff=1, lumped=False):
        nfaces, dim = self.mesh.nfaces, self.mesh.dimension
        massloc = barycentric.crbdryothers(dim)
        # lumped = False
        if colors is None: colors = self.mesh.bdrylabels.keys()

        if not isinstance(coeff, dict):
            faces = self.mesh.bdryFaces(colors)
            normalsS = self.mesh.normals[faces]
            dS = linalg.norm(normalsS, axis=1)
            if isinstance(coeff, (int, float)): dS *= coeff
            elif coeff.shape[0] == self.mesh.nfaces: dS *= coeff[faces]
            elif coeff.shape[0] == dS.shape[0]: dS *= coeff
            else: raise ValueError(f"cannot handle {coeff=}")
            AD = sparse.coo_matrix((dS, (faces, faces)),
                                   shape=(nfaces, nfaces))
            if lumped: return AD
            ci = self.mesh.cellsOfFaces[faces][:, 0]
            foc = self.mesh.facesOfCells[ci]
            mask = foc != faces[:, np.newaxis]
            # print(f"{mask=}")
            fi = foc[mask].reshape(foc.shape[0], foc.shape[1] - 1)
            # print(f"{massloc=}")
            cols = np.tile(fi, dim).ravel()
            rows = np.repeat(fi, dim).ravel()
            mat = np.einsum('n,kl->nkl', dS, massloc).ravel()
            return AD + sparse.coo_matrix(
                (mat, (rows, cols)), shape=(nfaces, nfaces))

        assert (isinstance(coeff, dict))
        rows = np.empty(shape=(0), dtype=int)
        cols = np.empty(shape=(0), dtype=int)
        mat = np.empty(shape=(0), dtype=float)
        for color in colors:
            faces = self.mesh.bdrylabels[color]
            normalsS = self.mesh.normals[faces]
            dS = linalg.norm(normalsS, axis=1) * coeff[color]
            cols = np.append(cols, faces)
            rows = np.append(rows, faces)
            mat = np.append(mat, dS)
            if not lumped:
                ci = self.mesh.cellsOfFaces[faces][:, 0]
                foc = self.mesh.facesOfCells[ci]
                mask = foc != faces[:, np.newaxis]
                fi = foc[mask].reshape(foc.shape[0], foc.shape[1] - 1)
                # print(f"{massloc=}")
                cols = np.append(cols, np.tile(fi, dim).ravel())
                rows = np.append(rows, np.repeat(fi, dim).ravel())
                mat = np.append(mat,
                                np.einsum('n,kl->nkl', dS, massloc).ravel())
        # print(f"{mat=}")
        return sparse.coo_matrix((mat, (rows, cols)),
                                 shape=(nfaces, nfaces)).tocsr()
Esempio n. 3
0
 def computeMatrixJump(self, betart, mode='primal', monotone=False):
     dim, dV, nfaces, ndofs = self.mesh.dimension, self.mesh.dV, self.mesh.nfaces, self.nunknowns(
     )
     nloc, dofspercell = self.nlocal(), self.dofspercell()
     innerfaces = self.mesh.innerfaces
     ci0 = self.mesh.cellsOfInteriorFaces[:, 0]
     ci1 = self.mesh.cellsOfInteriorFaces[:, 1]
     normalsS = self.mesh.normals[innerfaces]
     dS = linalg.norm(normalsS, axis=1)
     faces = self.mesh.faces[self.mesh.innerfaces]
     # ind0 = npext.positionin(faces, self.mesh.simplices[ci0])
     # ind1 = npext.positionin(faces, self.mesh.simplices[ci1])
     # fi0 = np.take_along_axis(self.mesh.facesOfCells[ci0], ind0, axis=1)
     # fi1 = np.take_along_axis(self.mesh.facesOfCells[ci1], ind1, axis=1)
     fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(ci0, ci1)
     ifaces = np.arange(nfaces)[innerfaces]
     A = sparse.coo_matrix((ndofs, ndofs))
     rows0 = np.repeat(fi0, nloc - 1).ravel()
     cols0 = np.tile(fi0, nloc - 1).ravel()
     rows1 = np.repeat(fi1, nloc - 1).ravel()
     cols1 = np.tile(fi1, nloc - 1).ravel()
     massloc = barycentric.crbdryothers(self.mesh.dimension)
     if mode == 'primal':
         mat = np.einsum('n,kl->nkl',
                         np.minimum(betart[innerfaces], 0) * dS,
                         massloc).ravel()
         A -= sparse.coo_matrix((mat, (rows0, cols0)), shape=(ndofs, ndofs))
         A += sparse.coo_matrix((mat, (rows0, cols1)), shape=(ndofs, ndofs))
         mat = np.einsum('n,kl->nkl',
                         np.maximum(betart[innerfaces], 0) * dS,
                         massloc).ravel()
         A -= sparse.coo_matrix((mat, (rows1, cols0)), shape=(ndofs, ndofs))
         A += sparse.coo_matrix((mat, (rows1, cols1)), shape=(ndofs, ndofs))
     elif mode == 'dual':
         mat = np.einsum('n,kl->nkl',
                         np.minimum(betart[innerfaces], 0) * dS,
                         massloc).ravel()
         A += sparse.coo_matrix((mat, (rows0, cols1)), shape=(ndofs, ndofs))
         A -= sparse.coo_matrix((mat, (rows1, cols1)), shape=(ndofs, ndofs))
         mat = np.einsum('n,kl->nkl',
                         np.maximum(betart[innerfaces], 0) * dS,
                         massloc).ravel()
         A += sparse.coo_matrix((mat, (rows0, cols0)), shape=(ndofs, ndofs))
         A -= sparse.coo_matrix((mat, (rows1, cols0)), shape=(ndofs, ndofs))
     elif mode == 'centered':
         mat = np.einsum('n,kl->nkl', betart[innerfaces] * dS,
                         massloc).ravel()
         A += sparse.coo_matrix((mat, (rows0, cols0)), shape=(ndofs, ndofs))
         A -= sparse.coo_matrix((mat, (rows1, cols1)), shape=(ndofs, ndofs))
     else:
         raise ValueError(f"unknown {mode=}")
     return A
Esempio n. 4
0
 def massDotBoundary(self,
                     b=None,
                     f=None,
                     colors=None,
                     coeff=1,
                     lumped=None):
     #TODO CR1 boundary integrals: can do at ones since last index in facesOfCells is the bdry side:
     # assert np.all(faces == foc[:,-1])
     if lumped is None: lumped = self.params_bool['masslumpedbdry']
     if colors is None: colors = self.mesh.bdrylabels.keys()
     massloc = barycentric.crbdryothers(self.mesh.dimension)
     if not isinstance(coeff, dict):
         faces = self.mesh.bdryFaces(colors)
         normalsS = self.mesh.normals[faces]
         dS = linalg.norm(normalsS, axis=1)
         if isinstance(coeff, (int, float)): dS *= coeff
         elif coeff.shape[0] == self.mesh.nfaces: dS *= coeff[faces]
         else: dS *= coeff
         if b is None: bsum = np.sum(dS * f[faces])
         else: b[faces] += dS * f[faces]
         if lumped:
             if b is None: return bsum
             else: return b
         else:
             ci = self.mesh.cellsOfFaces[faces][:, 0]
             foc = self.mesh.facesOfCells[ci]
             mask = foc != faces[:, np.newaxis]
             fi = foc[mask].reshape(foc.shape[0], foc.shape[1] - 1)
             r = np.einsum('n,kl,nl->nk', dS, massloc, f[fi])
             if b is None: return bsum + np.sum(r)
             # print(f"{np.linalg.norm(f[fi])=}")
             np.add.at(b, fi, r)
             return b
     assert (isinstance(coeff, dict))
     for color in colors:
         faces = self.mesh.bdrylabels[color]
         normalsS = self.mesh.normals[faces]
         dS = linalg.norm(normalsS, axis=1)
         dS *= coeff[color]
         b[faces] += dS * f[faces]
         if lumped: continue
         ci = self.mesh.cellsOfFaces[faces][:, 0]
         foc = self.mesh.facesOfCells[ci]
         mask = foc != faces[:, np.newaxis]
         fi = foc[mask].reshape(foc.shape[0], foc.shape[1] - 1)
         r = np.einsum('n,kl,nl->nk', dS, massloc, f[fi])
         # print(f"{np.linalg.norm(f[fi])=}")
         np.add.at(b, fi, r)
     return b
Esempio n. 5
0
 def computeMatrixHdivPenaly(self, coef=1):
     ncomp = self.ncomp
     dim, dV, ndofs, nloc = self.mesh.dimension, self.mesh.dV, self.nunknowns(
     ), self.nlocal()
     nall = ncomp * ndofs
     ci0 = self.mesh.cellsOfInteriorFaces[:, 0]
     ci1 = self.mesh.cellsOfInteriorFaces[:, 1]
     assert np.all(ci1 >= 0)
     normalsS = self.mesh.normals[self.mesh.innerfaces, :dim]
     dS = linalg.norm(normalsS, axis=1)
     fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(ci0, ci1)
     massloc = barycentric.crbdryothers(dim)
     if isinstance(coef, (int, float)):
         scale = coef / (dV[ci0] + dV[ci1])
     else:
         assert coef.shape == (self.mesh.ncells)
         scale = (coef[ci0] + coef[ci1]) / (dV[ci0] + dV[ci1])
     A = sparse.coo_matrix((nall, nall))
     for icomp in range(ncomp):
         d0i = ncomp * fi0 + icomp
         d1i = ncomp * fi1 + icomp
         rows0i = d0i.repeat(nloc - 1)
         rows1i = d1i.repeat(nloc - 1)
         for jcomp in range(ncomp):
             d0j = ncomp * fi0 + jcomp
             d1j = ncomp * fi1 + jcomp
             cols0j = np.tile(d0j, nloc - 1).ravel()
             cols1j = np.tile(d1j, nloc - 1).ravel()
             mat = np.einsum(
                 'n,kl->nkl',
                 normalsS[:, icomp] * normalsS[:, jcomp] * scale,
                 massloc).ravel()
             # print(f"{mat=}")
             A += sparse.coo_matrix((mat, (rows0i, cols0j)),
                                    shape=(nall, nall))
             A += sparse.coo_matrix((-mat, (rows0i, cols1j)),
                                    shape=(nall, nall))
             A += sparse.coo_matrix((-mat, (rows1i, cols0j)),
                                    shape=(nall, nall))
             A += sparse.coo_matrix((mat, (rows1i, cols1j)),
                                    shape=(nall, nall))
     # print(f"{A.A=}")
     return A
Esempio n. 6
0
 def computeFormJump(self, du, u, betart, mode='primal'):
     dim, dV, nfaces, ndofs = self.mesh.dimension, self.mesh.dV, self.mesh.nfaces, self.nunknowns(
     )
     nloc, dofspercell = self.nlocal(), self.dofspercell()
     innerfaces = self.mesh.innerfaces
     ci0 = self.mesh.cellsOfInteriorFaces[:, 0]
     ci1 = self.mesh.cellsOfInteriorFaces[:, 1]
     normalsS = self.mesh.normals[innerfaces]
     dS = linalg.norm(normalsS, axis=1)
     faces = self.mesh.faces[self.mesh.innerfaces]
     # ind0 = npext.positionin(faces, self.mesh.simplices[ci0])
     # ind1 = npext.positionin(faces, self.mesh.simplices[ci1])
     # fi0 = np.take_along_axis(self.mesh.facesOfCells[ci0], ind0, axis=1)
     # fi1 = np.take_along_axis(self.mesh.facesOfCells[ci1], ind1, axis=1)
     fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(ci0, ci1)
     # fi0, fi1 = self.mesh.facesOfCellsNotOnFaces(faces, ci0, ci1)
     # ifaces = np.arange(nfaces)[innerfaces]
     # A = sparse.coo_matrix((ndofs, ndofs))
     # rows0 = np.repeat(fi0, nloc-1).ravel()
     # cols0 = np.tile(fi0,nloc-1).ravel()
     # rows1 = np.repeat(fi1, nloc-1).ravel()
     # cols1 = np.tile(fi1,nloc-1).ravel()
     massloc = barycentric.crbdryothers(self.mesh.dimension)
     if mode == 'primal':
         mat = np.einsum('n,kl,nl->nk',
                         np.minimum(betart[innerfaces], 0) * dS, massloc,
                         u[fi1] - u[fi0])
         np.add.at(du, fi0, mat)
         mat = np.einsum('n,kl,nl->nk',
                         np.maximum(betart[innerfaces], 0) * dS, massloc,
                         u[fi1] - u[fi0])
         np.add.at(du, fi1, mat)
     elif mode == 'dual':
         assert 0
     elif mode == 'centered':
         assert 0
     else:
         raise ValueError(f"unknown {mode=}")
Esempio n. 7
0
 def computeFormHdivPenaly(self, du, u, coef=1):
     ncomp = self.ncomp
     dim, dV, ndofs = self.mesh.dimension, self.mesh.dV, self.nunknowns()
     ci0 = self.mesh.cellsOfInteriorFaces[:, 0]
     ci1 = self.mesh.cellsOfInteriorFaces[:, 1]
     assert np.all(ci1 >= 0)
     normalsS = self.mesh.normals[self.mesh.innerfaces, :dim]
     dS = linalg.norm(normalsS, axis=1)
     faces = self.mesh.faces[self.mesh.innerfaces]
     fi0, fi1 = self.mesh.facesOfCellsNotOnInnerFaces(ci0, ci1)
     massloc = barycentric.crbdryothers(dim)
     if isinstance(coef, (int, float)):
         scale = coef / (dV[ci0] + dV[ci1])
     else:
         assert coef.shape == (self.mesh.ncells)
         scale = (coef[ci0] + coef[ci1]) / (dV[ci0] + dV[ci1])
     for icomp in range(ncomp):
         u = u.reshape((dim, ndofs), order='F')
         # print(f"{normalsS.shape} {u[:,fi0].shape=}")
         r = np.einsum('n,nj,kl,jnl->nk', normalsS[:, icomp] * scale,
                       normalsS, massloc, u[:, fi0] - u[:, fi1])
         np.add.at(du, ncomp * fi0 + icomp, r)
         np.add.at(du, ncomp * fi1 + icomp, -r)