示例#1
0
    def jacobian(self, state):
        '''Jacobian J of F in M * du / dt = F(u) defined on the
        domain map used by HYMLS.'''

        state_ass = Vector(self.assembly_map)
        state_ass.Import(state, self.assembly_importer, Epetra.Insert)

        local_jac = fvm.Interface.jacobian(self, state_ass)

        if self.jac is None:
            self.jac = Epetra.FECrsMatrix(Epetra.Copy, self.solve_map, 27)
        else:
            self.jac.PutScalar(0.0)

        for i in range(len(local_jac.begA)-1):
            if self.is_ghost(i):
                continue
            row = self.assembly_map.GID64(i)
            for j in range(local_jac.begA[i], local_jac.begA[i+1]):
                # __setitem__ automatically calls ReplaceGlobalValues if the matrix is filled,
                # InsertGlobalValues otherwise
                self.jac[row, self.assembly_map.GID64(local_jac.jcoA[j])] = local_jac.coA[j]
        self.jac.GlobalAssemble(True, Epetra.Insert)

        return self.jac
示例#2
0
    def matmat(self, other):

        from PyTrilinos import Epetra
        from block.block_util import isscalar
        try:
            if isscalar(other):
                C = type(self.M)(self.M)
                if other != 1:
                    C.Scale(other)
                return matrix_op(C, self.transposed)
            other = other.down_cast()
            if hasattr(other, 'mat'):
                from PyTrilinos import EpetraExt

                # Create result matrix C. This is done in a contorted way, to
                # ensure all diagonals are present.
                A = type(self.M)(self.M)
                A.PutScalar(1.0)
                B = type(other.mat())(other.mat())
                B.PutScalar(1.0)
                C = Epetra.FECrsMatrix(Epetra.Copy, self.rowmap(), 100)
                EpetraExt.Multiply(A, self.transposed, B, other.transposed, C)
                C.OptimizeStorage()
                # C is now finalised, we can use it to store the real mat-mat product.

                assert (0 == EpetraExt.Multiply(self.M, self.transposed,
                                                other.mat(), other.transposed,
                                                C))

                result = matrix_op(C)

                # Sanity check. Cannot trust EpetraExt.Multiply always, it seems.
                from block import block_vec
                v = result.create_vec()
                block_vec([v]).randomize()
                xv = self * other * v
                err = (xv - result * v).norm('l2') / (xv).norm('l2')
                if (err > 1e-3):
                    print('++ a :', self * other)
                    print('++ a\':', result)
                    print(
                        '++ EpetraExt.Multiply computed wrong result; ||(a-a\')x||/||ax|| = %g'
                        % err)

                return result
            else:
                C = type(self.M)(self.M)
                if self.transposed:
                    C.LeftScale(other.vec())
                else:
                    C.RightScale(other.vec())
                return matrix_op(C, self.transposed)
        except AttributeError:
            raise TypeError("can't extract matrix data from type '%s'" %
                            str(type(other)))
示例#3
0
 def matmat(self, other):
     from PyTrilinos import Epetra
     try:
         from block.block_util import isscalar
         if isscalar(other):
             x = Epetra.Vector(self.v)
             x.Scale(other)
             return diag_op(x)
         other = other.down_cast()
         if hasattr(other, 'mat'):
             C = Epetra.FECrsMatrix(other.mat())
             C.LeftScale(self.v)
             return matrix_op(C)
         else:
             x = Epetra.Vector(self.v.Map())
             x.Multiply(1.0, self.v, other.vec(), 0.0)
             return diag_op(x)
     except AttributeError:
         raise TypeError("can't extract matrix data from type '%s'"%str(type(other)))
示例#4
0
    def add(self, other, lscale=1.0, rscale=1.0):
        try:
            other = other.down_cast()
        except AttributeError:
            #raise TypeError("can't extract matrix data from type '%s'"%str(type(other)))
            pass

        if hasattr(other, 'mat'):
            from PyTrilinos import Epetra, EpetraExt
            C = Epetra.FECrsMatrix(Epetra.Copy, self.rowmap(), 100)
            assert (0 == EpetraExt.Add(self.M,      self.transposed,  lscale, C, 0.0))
            assert (0 == EpetraExt.Add(other.mat(), other.transposed, rscale, C, 1.0))
            C.FillComplete()
            C.OptimizeStorage()
            return matrix_op(C)
        else:
            lhs = self.matmat(lscale)
            D = Diag(lhs).add(other, rscale=rscale)
            lhs.M.ReplaceDiagonalValues(D.vec())
            return lhs
示例#5
0
    def mass_matrix(self):
        '''Mass matrix M in M * du / dt = F(u) defined on the
        domain map used by HYMLS.'''

        local_mass = fvm.Interface.mass_matrix(self)

        if self.mass is None:
            self.mass = Epetra.FECrsMatrix(Epetra.Copy, self.solve_map, 1)
        else:
            self.mass.PutScalar(0.0)

        for i in range(len(local_mass.begA)-1):
            if self.is_ghost(i):
                continue
            row = self.assembly_map.GID64(i)
            for j in range(local_mass.begA[i], local_mass.begA[i+1]):
                # __setitem__ automatically calls ReplaceGlobalValues if the matrix is filled,
                # InsertGlobalValues otherwise
                self.mass[row, self.assembly_map.GID64(local_mass.jcoA[j])] = local_mass.coA[j]
        self.mass.GlobalAssemble(True, Epetra.Insert)

        return self.mass