// SmootherBase test ST::magnitudeType testApply(const Matrix& A, const SmootherBase & smoother, MultiVector & X, const MultiVector & RHS, Teuchos::FancyOStream & out, bool & success) { Array<ST::magnitudeType> norms(1); RHS.norm2(norms); out << "||RHS|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << norms[0] << std::endl; Teuchos::Array<ST::magnitudeType> initialNorms(1); X.norm2(initialNorms); out << "||X_initial|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << initialNorms[0] << std::endl; smoother.Apply(X, RHS); // TODO: bool const &InitialGuessIsZero=false Teuchos::Array<ST::magnitudeType> finalNorms(1); X.norm2(finalNorms); out << "||X_final|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(25) << norms[0] << std::endl; Teuchos::Array<ST::magnitudeType> residualNorms = Utils::ResidualNorm(A, X, RHS); out << "||Residual|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(20) << residualNorms[0] << std::endl; return residualNorms[0]; }
// Tests two sweeps of ILUT in Ifpack2 TEUCHOS_UNIT_TEST_TEMPLATE_4_DECL(Ifpack2Smoother, ILU_TwoSweeps, Scalar, LocalOrdinal, GlobalOrdinal, Node) { # include <MueLu_UseShortNames.hpp> MUELU_TESTING_SET_OSTREAM; MUELU_TESTING_LIMIT_EPETRA_SCOPE(Scalar,GlobalOrdinal,Node); typedef typename Teuchos::ScalarTraits<SC>::magnitudeType magnitude_type; MUELU_TEST_ONLY_FOR(Xpetra::UseTpetra) { //FIXME this will probably fail in parallel b/c it becomes block Jacobi Teuchos::ParameterList paramList; Ifpack2Smoother smoother("ILUT",paramList); //I don't use the testApply infrastructure because it has no provision for an initial guess. Teuchos::RCP<Matrix> A = TestHelpers::TestFactory<SC, LO, GO, NO>::Build1DPoisson(125); Level level; TestHelpers::TestFactory<SC,LO,GO,NO>::createSingleLevelHierarchy(level); level.Set("A", A); smoother.Setup(level); RCP<MultiVector> X = MultiVectorFactory::Build(A->getDomainMap(),1); RCP<MultiVector> RHS = MultiVectorFactory::Build(A->getRangeMap(),1); // Random X X->setSeed(846930886); X->randomize(); // Normalize X Array<magnitude_type> norms(1); X->norm2(norms); X->scale(1/norms[0]); // Compute RHS corresponding to X A->apply(*X,*RHS, Teuchos::NO_TRANS,(SC)1.0,(SC)0.0); // Reset X to 0 X->putScalar((SC) 0.0); RHS->norm2(norms); out << "||RHS|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << norms[0] << std::endl; out << "solve with zero initial guess" << std::endl; Teuchos::Array<magnitude_type> initialNorms(1); X->norm2(initialNorms); out << " ||X_initial|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << initialNorms[0] << std::endl; smoother.Apply(*X, *RHS, true); //zero initial guess Teuchos::Array<magnitude_type> finalNorms(1); X->norm2(finalNorms); Teuchos::Array<magnitude_type> residualNorm1 = Utilities::ResidualNorm(*A, *X, *RHS); out << " ||Residual_final|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(20) << residualNorm1[0] << std::endl; out << " ||X_final|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << finalNorms[0] << std::endl; out << "solve with random initial guess" << std::endl; X->randomize(); X->norm2(initialNorms); out << " ||X_initial|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << initialNorms[0] << std::endl; smoother.Apply(*X, *RHS, false); //nonzero initial guess X->norm2(finalNorms); Teuchos::Array<magnitude_type> residualNorm2 = Utilities::ResidualNorm(*A, *X, *RHS); out << " ||Residual_final|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(20) << residualNorm2[0] << std::endl; out << " ||X_final|| = " << std::setiosflags(std::ios::fixed) << std::setprecision(10) << finalNorms[0] << std::endl; RCP<const Teuchos::Comm<int> > comm = TestHelpers::Parameters::getDefaultComm(); if (comm->getSize() == 1) { //TEST_EQUALITY(residualNorms < 1e-10, true); TEST_EQUALITY(residualNorm1[0] != residualNorm2[0], true); } else { out << "Pass/Fail is only checked in serial." << std::endl; } } } // ILU