void PrecPrecomputed::applyTempl( const Tpetra::MultiVector<DomainScalar, Ordinal, Ordinal, Node>& X, Tpetra::MultiVector<RangeScalar, Ordinal, Ordinal, Node>& Z, Teuchos::ETransp mode, RangeScalar alpha, RangeScalar beta) const { using Teuchos::RCP; using Teuchos::rcp; typedef Tpetra::MultiVector<DomainScalar, Ordinal, Ordinal, Node> MV; Teuchos::Time timer ("ILUT::apply"); { // Timer scope for timing apply() Teuchos::TimeMonitor timeMon (timer, true); TEUCHOS_TEST_FOR_EXCEPTION( ! isComputed (), std::runtime_error, "Ifpack2::ILUT::apply: You must call compute() to compute the incomplete " "factorization, before calling apply()."); TEUCHOS_TEST_FOR_EXCEPTION( X.getNumVectors() != Z.getNumVectors(), std::runtime_error, "Ifpack2::ILUT::apply: X and Y must have the same number of columns. " "X has " << X.getNumVectors () << " columns, but Y has " << Z.getNumVectors () << " columns."); TEUCHOS_TEST_FOR_EXCEPTION( beta != STS::zero (), std::logic_error, "Ifpack2::ILUT::apply: This method does not currently work when beta != 0."); // If X and Y are pointing to the same memory location, // we need to create an auxiliary vector, Xcopy RCP<const MV> Xcopy; if (X.getLocalMV ().getValues () == Z.getLocalMV ().getValues ()) { Xcopy = rcp (new MV (X)); } else { Xcopy = rcpFromRef (X); //ZACH always taken } //if (mode == Teuchos::NO_TRANS) { // Solve L U Y = X /* L_->template localSolve<RangeScalar,DomainScalar> (*Xcopy, Y, Teuchos::NO_TRANS); U_->template localSolve<RangeScalar,RangeScalar> (Y, Y, Teuchos::NO_TRANS); */ //dump(X, "##X"); //dump(*Xcopy, "##Xcopy"); //ZACH the problem is here: This actually needs to be a global triangular solve L_->template localSolve<RangeScalar,DomainScalar> (*Xcopy, *Y_, Teuchos::NO_TRANS); //dump(*Y_, "##Y"); U_->template localSolve<RangeScalar,RangeScalar> (*Y_, Z, Teuchos::NO_TRANS); //U_->template localSolve<RangeScalar,RangeScalar> (*Xcopy, Z, Teuchos::NO_TRANS); //dump(Z, "##Z"); //U_->template localSolve<RangeScalar,DomainScalar> (*Xcopy, Y, Teuchos::NO_TRANS); //U_->template localSolve<RangeScalar,RangeScalar> (Y, Y, Teuchos::TRANS); //} //else { // Solve U^* L^* Y = X /* U_->template localSolve<RangeScalar,DomainScalar> (*Xcopy, Y, mode); L_->template localSolve<RangeScalar,RangeScalar> (Y, Y, mode); */ //} if (alpha != STS::one ()) { Z.scale (alpha); } } ++NumApply_; ApplyTime_ += timer.totalElapsedTime (); }
void SupportGraph<MatrixType>:: apply (const Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& X, Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type>& Y, Teuchos::ETransp mode, scalar_type alpha, scalar_type beta) const { using Teuchos::FancyOStream; using Teuchos::getFancyOStream; using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcpFromRef; using Teuchos::Time; using Teuchos::TimeMonitor; typedef scalar_type DomainScalar; typedef scalar_type RangeScalar; typedef Tpetra::MultiVector<DomainScalar, local_ordinal_type, global_ordinal_type, node_type> MV; RCP<FancyOStream> out = getFancyOStream(rcpFromRef(std::cout)); // Create a timer for this method, if it doesn't exist already. // TimeMonitor::getNewCounter registers the timer, so that // TimeMonitor's class methods like summarize() will report the // total time spent in successful calls to this method. const std::string timerName ("Ifpack2::SupportGraph::apply"); RCP<Time> timer = TimeMonitor::lookupCounter(timerName); if (timer.is_null()) { timer = TimeMonitor::getNewCounter(timerName); } { // Start timing here. Teuchos::TimeMonitor timeMon (*timer); TEUCHOS_TEST_FOR_EXCEPTION( ! isComputed(), std::runtime_error, "Ifpack2::SupportGraph::apply: You must call compute() to compute the " "incomplete factorization, before calling apply()."); TEUCHOS_TEST_FOR_EXCEPTION( X.getNumVectors() != Y.getNumVectors(), std::runtime_error, "Ifpack2::SupportGraph::apply: X and Y must have the same number of " "columns. X has " << X.getNumVectors() << " columns, but Y has " << Y.getNumVectors() << " columns."); TEUCHOS_TEST_FOR_EXCEPTION( beta != STS::zero(), std::logic_error, "Ifpack2::SupportGraph::apply: This method does not currently work when " "beta != 0."); // If X and Y are pointing to the same memory location, // we need to create an auxiliary vector, Xcopy RCP<const MV> Xcopy; if (X.getLocalMV().getValues() == Y.getLocalMV().getValues()) { Xcopy = rcp (new MV(X)); } else { Xcopy = rcpFromRef(X); } if (alpha != STS::one()) { Y.scale(alpha); } RCP<MV> Ycopy = rcpFromRef(Y); solver_->setB(Xcopy); solver_->setX(Ycopy); solver_->solve (); } // Stop timing here. ++NumApply_; // timer->totalElapsedTime() returns the total time over all timer // calls. Thus, we use = instead of +=. ApplyTime_ = timer->totalElapsedTime(); }