void TomBlockRelaxation<MatrixType,ContainerType>::apply( const Tpetra::MultiVector<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>& X, Tpetra::MultiVector<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>& Y, Teuchos::ETransp mode, Scalar alpha, Scalar beta) const { TEUCHOS_TEST_FOR_EXCEPTION(isComputed() == false, std::runtime_error, "Ifpack2::TomBlockRelaxation::apply ERROR: isComputed() must be true prior to calling apply."); TEUCHOS_TEST_FOR_EXCEPTION(X.getNumVectors() != Y.getNumVectors(), std::runtime_error, "Ifpack2::TomBlockRelaxation::apply ERROR: X.getNumVectors() != Y.getNumVectors()."); TEUCHOS_TEST_FOR_EXCEPTION(mode != Teuchos::NO_TRANS, std::runtime_error, "Ifpack2::TomBlockRelaxation::apply ERORR: transpose modes not supported."); Time_->start(true); // If X and Y are pointing to the same memory location, // we need to create an auxiliary vector, Xcopy Teuchos::RCP< const Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > Xcopy; if (X.getLocalMV().getValues() == Y.getLocalMV().getValues()) Xcopy = Teuchos::rcp( new Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>(X) ); else Xcopy = Teuchos::rcp( &X, false ); if (ZeroStartingSolution_) Y.putScalar(0.0); // Flops are updated in each of the following. switch (PrecType_) { case Ifpack2::JACOBI: ApplyInverseJacobi(*Xcopy,Y); break; case Ifpack2::GS: ApplyInverseGS(*Xcopy,Y); break; case Ifpack2::SGS: ApplyInverseSGS(*Xcopy,Y); break; default: throw std::runtime_error("Ifpack2::TomBlockRelaxation::apply internal logic error."); } ++NumApply_; Time_->stop(); ApplyTime_ += Time_->totalElapsedTime(); }
void Hiptmair<MatrixType>:: apply (const Tpetra::MultiVector<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>& X, Tpetra::MultiVector<typename MatrixType::scalar_type, typename MatrixType::local_ordinal_type, typename MatrixType::global_ordinal_type, typename MatrixType::node_type>& Y, Teuchos::ETransp mode, typename MatrixType::scalar_type alpha, typename MatrixType::scalar_type beta) const { using Teuchos::RCP; using Teuchos::rcp; using Teuchos::rcpFromRef; typedef Tpetra::MultiVector<scalar_type, local_ordinal_type, global_ordinal_type, node_type> MV; TEUCHOS_TEST_FOR_EXCEPTION( ! isComputed (), std::runtime_error, "Ifpack2::Hiptmair::apply: You must call compute() before you may call apply()."); TEUCHOS_TEST_FOR_EXCEPTION( X.getNumVectors () != Y.getNumVectors (), std::invalid_argument, "Ifpack2::Hiptmair::apply: The MultiVector inputs X and Y do not have the " "same number of columns. X.getNumVectors() = " << X.getNumVectors () << " != Y.getNumVectors() = " << Y.getNumVectors () << "."); // Catch unimplemented cases: alpha != 1, beta != 0, mode != NO_TRANS. TEUCHOS_TEST_FOR_EXCEPTION( alpha != STS::one (), std::logic_error, "Ifpack2::Hiptmair::apply: alpha != 1 has not been implemented."); TEUCHOS_TEST_FOR_EXCEPTION( beta != STS::zero (), std::logic_error, "Ifpack2::Hiptmair::apply: zero != 0 has not been implemented."); TEUCHOS_TEST_FOR_EXCEPTION( mode != Teuchos::NO_TRANS, std::logic_error, "Ifpack2::Hiptmair::apply: mode != Teuchos::NO_TRANS has not been implemented."); Teuchos::Time timer ("apply"); { // The body of code to time Teuchos::TimeMonitor timeMon (timer); // 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, Teuchos::Copy)); } else { Xcopy = rcpFromRef (X); } RCP<MV> Ycopy = rcpFromRef (Y); if (ZeroStartingSolution_) { Ycopy->putScalar (STS::zero ()); } // apply Hiptmair Smoothing applyHiptmairSmoother (*Xcopy, *Ycopy); } ++NumApply_; ApplyTime_ += timer.totalElapsedTime (); }
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(); }