void DropFilter<MatrixType>::getLocalRowCopy(LocalOrdinal LocalRow, const Teuchos::ArrayView<LocalOrdinal> &Indices, const Teuchos::ArrayView<Scalar> &Values, size_t &NumEntries) const { TEUCHOS_TEST_FOR_EXCEPTION((LocalRow < 0 || (size_t) LocalRow >= NumRows_ || (size_t) Indices.size() < NumEntries_[LocalRow]), std::runtime_error, "Ifpack2::DropFilter::getLocalRowCopy invalid row or array size."); // Note: This function will work correctly if called by apply, say, with Indices_ and Values_ as // parameters. The structure of the loop below should make that obvious. // always extract using the object Values_ and Indices_. // This is because I need more space than that given by // the user (for the external nodes) size_t A_NumEntries=0; A_->getLocalRowCopy(LocalRow,Indices_(),Values_(),A_NumEntries); // loop over all nonzero elements of row MyRow, // and drop elements below specified threshold. // Also, add value to zero diagonal NumEntries = 0; for (size_t i = 0 ; i < A_NumEntries ; ++i) { // if element is above specified tol, add to the // user's defined arrays. Check that we are not // exceeding allocated space. Do not drop any diagonal entry. if ((Indices_[i] == LocalRow) || (Teuchos::ScalarTraits<Scalar>::magnitude(Values_[i]) >= DropTol_)) { Values[NumEntries] = Values_[i]; Indices[NumEntries] = Indices_[i]; NumEntries++; } } }
void SingletonFilter<MatrixType>::CreateReducedRHSTempl(const Tpetra::MultiVector<DomainScalar,LocalOrdinal,GlobalOrdinal,Node>& LHS, const Tpetra::MultiVector<RangeScalar,LocalOrdinal,GlobalOrdinal,Node>& RHS, Tpetra::MultiVector<RangeScalar,LocalOrdinal,GlobalOrdinal,Node>& ReducedRHS) { Teuchos::ArrayRCP<Teuchos::ArrayRCP<const RangeScalar > > RHS_ptr = RHS.get2dView(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<const DomainScalar> > LHS_ptr = LHS.get2dView(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<RangeScalar> > ReducedRHS_ptr = ReducedRHS.get2dViewNonConst(); size_t NumVectors = LHS.getNumVectors(); for (size_t i = 0 ; i < NumRows_ ; ++i) for (size_t k = 0 ; k < NumVectors ; ++k) ReducedRHS_ptr[k][i] = RHS_ptr[k][InvReorder_[i]]; for (size_t i = 0 ; i < NumRows_ ; ++i) { LocalOrdinal ii = InvReorder_[i]; size_t Nnz; A_->getLocalRowCopy(ii,Indices_(),Values_(),Nnz); for (size_t j = 0 ; j < Nnz ; ++j) { if (Reorder_[Indices_[j]] == -1) { for (size_t k = 0 ; k < NumVectors ; ++k) ReducedRHS_ptr[k][i] -= (RangeScalar)Values_[j] * (RangeScalar)LHS_ptr[k][Indices_[j]]; } } } }
void SingletonFilter<MatrixType>::SolveSingletonsTempl(const Tpetra::MultiVector<DomainScalar,LocalOrdinal,GlobalOrdinal,Node>& RHS, Tpetra::MultiVector<RangeScalar,LocalOrdinal,GlobalOrdinal,Node>& LHS) { Teuchos::ArrayRCP<Teuchos::ArrayRCP<const DomainScalar> > RHS_ptr = RHS.get2dView(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<RangeScalar> > LHS_ptr = LHS.get2dViewNonConst(); for (size_t i = 0 ; i < NumSingletons_ ; ++i) { LocalOrdinal ii = SingletonIndex_[i]; // get the diagonal value for the singleton size_t Nnz; A_->getLocalRowCopy(ii,Indices_(),Values_(),Nnz); for (size_t j = 0 ; j < Nnz ; ++j) { if (Indices_[j] == ii) { for (size_t k = 0 ; k < LHS.getNumVectors() ; ++k) LHS_ptr[k][ii] = (RangeScalar)RHS_ptr[k][ii] / (RangeScalar)Values_[j]; } } } }
void SingletonFilter<MatrixType>::apply(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &X, Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp mode, Scalar alpha, Scalar beta) const { typedef Scalar DomainScalar; typedef Scalar RangeScalar; // Note: This isn't AztecOO compliant. But neither was Ifpack's version. TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error, "Ifpack2::SingletonFilter::apply ERROR: X.getNumVectors() != Y.getNumVectors()."); RangeScalar zero = Teuchos::ScalarTraits<RangeScalar>::zero(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<const DomainScalar> > x_ptr = X.get2dView(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<RangeScalar> > y_ptr = Y.get2dViewNonConst(); Y.putScalar(zero); size_t NumVectors = Y.getNumVectors(); for (size_t i = 0 ; i < NumRows_ ; ++i) { size_t Nnz; // Use this class's getrow to make the below code simpler getLocalRowCopy(i,Indices_(),Values_(),Nnz); if (mode==Teuchos::NO_TRANS){ for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][i] += (RangeScalar)Values_[j] * (RangeScalar)x_ptr[k][Indices_[j]]; } else if (mode==Teuchos::TRANS){ for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][Indices_[j]] += (RangeScalar)Values_[j] * (RangeScalar)x_ptr[k][i]; } else { //mode==Teuchos::CONJ_TRANS for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][Indices_[j]] += Teuchos::ScalarTraits<RangeScalar>::conjugate((RangeScalar)Values_[j]) * (RangeScalar)x_ptr[k][i]; } } }
void DropFilter<MatrixType>::apply(const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &X, Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> &Y, Teuchos::ETransp mode, Scalar /* alpha */, Scalar /* beta */) const { // Note: This isn't AztecOO compliant. But neither was Ifpack's version. // Note: The localized maps mean the matvec is trivial (and has no import) TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error, "Ifpack2::DropFilter::apply ERROR: X.getNumVectors() != Y.getNumVectors()."); Scalar zero = Teuchos::ScalarTraits<Scalar>::zero(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<const Scalar> > x_ptr = X.get2dView(); Teuchos::ArrayRCP<Teuchos::ArrayRCP<Scalar> > y_ptr = Y.get2dViewNonConst(); Y.putScalar(zero); size_t NumVectors = Y.getNumVectors(); for (size_t i = 0 ; i < NumRows_ ; ++i) { size_t Nnz; // Use this class's getrow to make the below code simpler getLocalRowCopy(i,Indices_(),Values_(),Nnz); if (mode==Teuchos::NO_TRANS){ for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][i] += Values_[j] * x_ptr[k][Indices_[j]]; } else if (mode==Teuchos::TRANS){ for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][Indices_[j]] += Values_[j] * x_ptr[k][i]; } else { //mode==Teuchos::CONJ_TRANS for (size_t j = 0 ; j < Nnz ; ++j) for (size_t k = 0 ; k < NumVectors ; ++k) y_ptr[k][Indices_[j]] += Teuchos::ScalarTraits<Scalar>::conjugate(Values_[j]) * x_ptr[k][i]; } } }
void SingletonFilter<MatrixType>::getLocalRowCopy(LocalOrdinal LocalRow, const Teuchos::ArrayView<LocalOrdinal> &Indices, const Teuchos::ArrayView<Scalar> &Values, size_t &NumEntries) const { TEUCHOS_TEST_FOR_EXCEPTION((LocalRow < 0 || (size_t) LocalRow >= NumRows_ || (size_t) Indices.size() < NumEntries_[LocalRow]), std::runtime_error, "Ifpack2::SingletonFilter::getLocalRowCopy invalid row or array size."); size_t Nnz; LocalOrdinal ARow = InvReorder_[LocalRow]; A_->getLocalRowCopy(ARow,Indices_(),Values_(),Nnz); // populate the user's vectors NumEntries = 0; for (size_t i = 0 ; i < Nnz ; ++i) { LocalOrdinal ii = Reorder_[Indices_[i]]; if ( ii >= 0) { Indices[NumEntries] = ii; Values[NumEntries] = Values_[i]; NumEntries++; } } }