예제 #1
0
  void solve_system_belos(
      RCP<Xpetra::Matrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> > & A,
      RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > & X,
      RCP<Xpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> > & B,
      Teuchos::ParameterList & MueLuList,
      const std::string & belos_solver,
      RCP<Teuchos::ParameterList> & SList) {
    using Teuchos::RCP;
    using Teuchos::rcp;
    typedef Tpetra::Operator<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tpetra_Operator;
    typedef Tpetra::CrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tpetra_CrsMatrix;
    typedef Tpetra::Experimental::BlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tpetra_BlockCrsMatrix;
    typedef Xpetra::TpetraBlockCrsMatrix<Scalar,LocalOrdinal,GlobalOrdinal,Node> Xpetra_TpetraBlockCrsMatrix;
    typedef Tpetra::Vector<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tpetra_Vector;
    typedef Tpetra::MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node> Tpetra_MultiVector;

    RCP<Tpetra_Operator>    At = MueLu::Utilities<Scalar,LocalOrdinal,GlobalOrdinal,Node>::Op2NonConstTpetraRow(A);
    RCP<Tpetra_Operator>    Mt = MueLu::CreateTpetraPreconditioner(At,MueLuList);
    RCP<Tpetra_MultiVector> Xt = Xpetra::toTpetra(*X);
    RCP<Tpetra_MultiVector> Bt = Xpetra::toTpetra(*B);

    if(Xt.is_null() || Bt.is_null() || At.is_null() || Mt.is_null()) throw std::runtime_error("ERROR: Xpetra to Tpetra conversion failed");

    typedef Tpetra_MultiVector MV;
    typedef Tpetra_Operator OP;
    RCP<Belos::LinearProblem<Scalar,MV,OP> > belosProblem = rcp(new Belos::LinearProblem<Scalar,MV,OP>(At, Xt, Bt));
    belosProblem->setLeftPrec(Mt);
    belosProblem->setProblem(Xt,Bt);

    Belos::SolverFactory<Scalar, MV, OP> BelosFactory;
    Teuchos::RCP<Belos::SolverManager<Scalar, MV, OP> > BelosSolver = BelosFactory.create(belos_solver, SList);
    BelosSolver->setProblem(belosProblem);
    BelosSolver->solve();
  }
예제 #2
0
  // --------------------------------------------------------------------------------------
  void solve_system_list(Xpetra::UnderlyingLib & lib, RCP<Matrix> & A, RCP<Vector>&  X, RCP<Vector> & B, Teuchos::ParameterList & MueLuList, RCP<Teuchos::ParameterList> & SList) {
    using Teuchos::RCP;
    using Teuchos::rcp;
#ifdef HAVE_MUELU_BELOS
#ifdef HAVE_MUELU_TPETRA
    typedef Tpetra::Operator<SC,LO,GO> Tpetra_Operator;
    typedef Tpetra::CrsMatrix<SC,LO,GO> Tpetra_CrsMatrix;
    typedef Tpetra::Vector<SC,LO,GO> Tpetra_Vector;
    typedef Tpetra::MultiVector<SC,LO,GO> Tpetra_MultiVector;
    if(lib==Xpetra::UseTpetra) {
      RCP<Tpetra_CrsMatrix>   At = Xpetra::MatrixMatrix::Op2NonConstTpetraCrs(A);
      RCP<Tpetra_Operator>    Mt = MueLu::CreateTpetraPreconditioner(At,MueLuList);
      RCP<Tpetra_MultiVector> Xt = Xpetra::toTpetra(*X);
      RCP<Tpetra_MultiVector> Bt = Xpetra::toTpetra(*B);
      typedef Tpetra_MultiVector MV;
      typedef Tpetra_Operator OP;
      RCP<Belos::LinearProblem<SC,MV,OP> > belosProblem = rcp(new Belos::LinearProblem<SC,MV,OP>(At, Xt, Bt));
      belosProblem->setRightPrec(Mt);
      belosProblem->setProblem(Xt,Bt);

      Belos::SolverFactory<SC, MV, OP> BelosFactory;
      Teuchos::RCP<Belos::SolverManager<SC, MV, OP> > BelosSolver = BelosFactory.create(std::string("CG"), SList);
      BelosSolver->setProblem(belosProblem);
      Belos::ReturnType result = BelosSolver->solve();
      if(result==Belos::Unconverged)
        throw std::runtime_error("Belos failed to converge");
    }
#endif
#ifdef HAVE_MUELU_EPETRA
    if(lib==Xpetra::UseEpetra) {
      RCP<Epetra_CrsMatrix>   Ae = Xpetra::MatrixMatrix::Op2NonConstEpetraCrs(A);
      RCP<Epetra_Operator>    Me = MueLu::CreateEpetraPreconditioner(Ae,MueLuList);
      RCP<Epetra_MultiVector> Xe = rcp(&Xpetra::toEpetra(*X),false);
      RCP<Epetra_MultiVector> Be = rcp(&Xpetra::toEpetra(*B),false);
      typedef Epetra_MultiVector MV;
      typedef Epetra_Operator OP;
      RCP<Belos::LinearProblem<SC,MV,OP> > belosProblem = rcp(new Belos::LinearProblem<SC,MV,OP>(Ae, Xe, Be));
      Teuchos::RCP<Belos::EpetraPrecOp> PrecWrap = Teuchos::rcp(new Belos::EpetraPrecOp(Me));
      belosProblem->setRightPrec(PrecWrap);
      belosProblem->setProblem(Xe,Be);

      Belos::SolverFactory<SC, MV, OP> BelosFactory;
      Teuchos::RCP<Belos::SolverManager<SC, MV, OP> > BelosSolver = BelosFactory.create(std::string("CG"), SList);
      BelosSolver->setProblem(belosProblem);
      Belos::ReturnType result = BelosSolver->solve();
      if(result==Belos::Unconverged)
        throw std::runtime_error("Belos failed to converge");
    }
#endif
#endif // #ifdef HAVE_MUELU_BELOS

  }
예제 #3
0
//-----------------------------------------------------------------------------
void BelosKrylovSolver::init(const std::string& method)
{
  Teuchos::RCP<Teuchos::ParameterList> dummy_params = Teuchos::parameterList();

  std::string method_name = method;
  if (method=="default")
    method_name = "GMRES";

  Belos::SolverFactory<double, TpetraVector::vector_type, op_type> factory;
  _solver = factory.create(method_name, dummy_params);

  _problem = Teuchos::rcp(new problem_type);
}
예제 #4
0
//-----------------------------------------------------------------------------
std::map<std::string, std::string> BelosKrylovSolver::methods()
{
  Belos::SolverFactory<double, TpetraVector::vector_type, op_type> factory;
  Teuchos::Array<std::string> methods = factory.supportedSolverNames();

  std::map<std::string, std::string> result;
  result.insert(std::make_pair("default", "default method"));

  for (auto &m : methods)
  {
    for (auto &c : m)
      c = std::tolower(c);
    result.insert(std::make_pair(m, m));
  }
  return result;
}
예제 #5
0
  int
main (int argc, char *argv[])
{
  using Teuchos::inOutArg;
  using Teuchos::ParameterList;
  using Teuchos::parameterList;
  using Teuchos::RCP;
  using Teuchos::rcp;
  using Teuchos::rcpFromRef;
  using std::endl;
  typedef double                          ST;
  typedef Epetra_Operator                 OP;
  typedef Epetra_MultiVector              MV;
  typedef Belos::OperatorTraits<ST,MV,OP> OPT;
  typedef Belos::MultiVecTraits<ST,MV>    MVT;

  // This calls MPI_Init and MPI_Finalize as necessary.
  Belos::Test::MPISession session (inOutArg (argc), inOutArg (argv));
  RCP<const Epetra_Comm> comm = session.getComm ();

  bool success = false;
  bool verbose = false;
  try {
    int MyPID = comm->MyPID ();

    //
    // Parameters to read from command-line processor
    //
    int frequency = -1;  // how often residuals are printed by solver
    int numRHS = 1;  // total number of right-hand sides to solve for
    int maxIters = 13000;  // maximum number of iterations for solver to use
    std::string filename ("bcsstk14.hb");
    double tol = 1.0e-5; // relative residual tolerance

    //
    // Read in command-line arguments
    //
    Teuchos::CommandLineProcessor cmdp (false, true);
    cmdp.setOption ("verbose", "quiet", &verbose, "Print messages and results.");
    cmdp.setOption ("frequency", &frequency, "Solvers frequency for printing "
        "residuals (#iters).");
    cmdp.setOption ("tol", &tol, "Relative residual tolerance used by MINRES "
        "solver.");
    cmdp.setOption ("filename", &filename, "Filename for Harwell-Boeing test "
        "matrix.");
    cmdp.setOption ("num-rhs", &numRHS, "Number of right-hand sides to solve.");
    cmdp.setOption ("max-iters", &maxIters, "Maximum number of iterations per "
        "linear system (-1 means \"adapt to problem/block size\").");
    if (cmdp.parse (argc,argv) != Teuchos::CommandLineProcessor::PARSE_SUCCESSFUL) {
      return EXIT_FAILURE;
    }
    Teuchos::oblackholestream blackHole;
    std::ostream& verbOut = (verbose && MyPID == 0) ? std::cout : blackHole;

    //
    // Generate the linear system(s) to solve.
    //
    verbOut << "Generating the linear system(s) to solve" << endl << endl;
    RCP<Epetra_CrsMatrix> A;
    RCP<Epetra_MultiVector> B, X;
    RCP<Epetra_Map> rowMap;
    try {
      // This might change the number of right-hand sides, if we read in
      // a right-hand side from the Harwell-Boeing file.
      Belos::Util::createEpetraProblem (filename, &rowMap, &A, &B, &X, &MyPID, numRHS);
    } catch (std::exception& e) {
      TEUCHOS_TEST_FOR_EXCEPTION (true, std::runtime_error,
          "Failed to create Epetra problem for matrix "
          "filename \"" << filename << "\".  "
          "createEpetraProblem() reports the following "
          "error: " << e.what());
    }
    //
    // Compute the initial residual norm of the problem, so we can see
    // by how much it improved after the solve.
    //
    std::vector<double> initialResidualNorms (numRHS);
    std::vector<double> initialResidualInfNorms (numRHS);
    Epetra_MultiVector R (*rowMap, numRHS);
    OPT::Apply (*A, *X, R);
    MVT::MvAddMv (-1.0, R, 1.0, *B, R); // R := -(A*X) + B.
    MVT::MvNorm (R, initialResidualNorms);
    MVT::MvNorm (R, initialResidualInfNorms, Belos::InfNorm);
    if (verbose) {
      verbOut << "Initial residual 2-norms:            \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << initialResidualNorms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl << "Initial residual Inf-norms:          \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << initialResidualInfNorms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl;
    }

    std::vector<double> rhs2Norms (numRHS);
    std::vector<double> rhsInfNorms (numRHS);
    MVT::MvNorm (*B, rhs2Norms);
    MVT::MvNorm (*B, rhsInfNorms, Belos::InfNorm);
    if (verbose) {
      verbOut << "Right-hand side 2-norms:             \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << rhs2Norms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl << "Right-hand side Inf-norms:           \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << rhsInfNorms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl;
    }

    std::vector<double> initialGuess2Norms (numRHS);
    std::vector<double> initialGuessInfNorms (numRHS);
    MVT::MvNorm (*X, initialGuess2Norms);
    MVT::MvNorm (*X, initialGuessInfNorms, Belos::InfNorm);
    if (verbose) {
      verbOut << "Initial guess 2-norms:               \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << initialGuess2Norms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl << "Initial guess Inf-norms:             \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << initialGuessInfNorms[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl;
    }
    //
    // Compute the infinity-norm of A.
    //
    const double normOfA = A->NormInf ();
    verbOut << "||A||_inf:                           \t" << normOfA << endl;
    //
    // Compute ||A|| ||X_i|| + ||B_i|| for each right-hand side B_i.
    //
    std::vector<double> scaleFactors (numRHS);
    for (int i = 0; i < numRHS; ++i) {
      scaleFactors[i] = normOfA * initialGuessInfNorms[i] + rhsInfNorms[i];
    }
    if (verbose) {
      verbOut << "||A||_inf ||X_i||_inf + ||B_i||_inf: \t";
      for (int i = 0; i < numRHS; ++i) {
        verbOut << scaleFactors[i];
        if (i < numRHS-1) {
          verbOut << ", ";
        }
      }
      verbOut << endl;
    }

    //
    // Solve using Belos
    //
    verbOut << endl << "Setting up Belos" << endl;
    const int NumGlobalElements = B->GlobalLength();

    // Set up Belos solver parameters.
    RCP<ParameterList> belosList = parameterList ("MINRES");
    belosList->set ("Maximum Iterations", maxIters);
    belosList->set ("Convergence Tolerance", tol);
    if (verbose) {
      belosList->set ("Verbosity", Belos::Errors + Belos::Warnings +
          Belos::IterationDetails + Belos::OrthoDetails +
          Belos::FinalSummary + Belos::TimingDetails + Belos::Debug);
      belosList->set ("Output Frequency", frequency);
    }
    else {
      belosList->set ("Verbosity", Belos::Errors + Belos::Warnings);
    }
    belosList->set ("Output Stream", rcpFromRef (verbOut));

    // Construct an unpreconditioned linear problem instance.
    typedef Belos::LinearProblem<double,MV,OP> prob_type;
    RCP<prob_type> problem = rcp (new prob_type (A, X, B));
    if (! problem->setProblem()) {
      verbOut << endl << "ERROR:  Failed to set up Belos::LinearProblem!" << endl;
      return EXIT_FAILURE;
    }

    // Create an iterative solver manager.
    Belos::SolverFactory<double, MV, OP> factory;
    RCP<Belos::SolverManager<double,MV,OP> > newSolver =
      factory.create ("MINRES", belosList);
    newSolver->setProblem (problem);

    // Print out information about problem.  Make sure to use the
    // information as stored in the Belos ParameterList, so that we know
    // what the solver will do.
    verbOut << endl
      << "Dimension of matrix: " << NumGlobalElements << endl
      << "Number of right-hand sides: " << numRHS << endl
      << "Max number of MINRES iterations: "
      << belosList->get<int> ("Maximum Iterations") << endl
      << "Relative residual tolerance: "
      << belosList->get<double> ("Convergence Tolerance") << endl
      << "Output frequency: "
      << belosList->get<int> ("Output Frequency") << endl
      << endl;

    // Solve the linear system.
    verbOut << "Solving the linear system" << endl << endl;
    Belos::ReturnType ret = newSolver->solve();
    verbOut << "Belos results:" << endl
      << "- Number of iterations: "
      << newSolver->getNumIters () << endl
      << "- " << (ret == Belos::Converged ? "Converged" : "Not converged")
      << endl;
    //
    // After the solve, compute residual(s) explicitly.  This tests
    // whether the Belos solver did so correctly.
    //
    std::vector<double> absoluteResidualNorms (numRHS);
    OPT::Apply (*A, *X, R);
    MVT::MvAddMv (-1.0, R, 1.0, *B, R);
    MVT::MvNorm (R, absoluteResidualNorms);

    std::vector<double> relativeResidualNorms (numRHS);
    for (int i = 0; i < numRHS; ++i) {
      relativeResidualNorms[i] = (initialResidualNorms[i] == 0.0) ?
        absoluteResidualNorms[i] :
        absoluteResidualNorms[i] / initialResidualNorms[i];
    }

    verbOut << "---------- Computed relative residual norms ----------"
      << endl << endl;
    bool badRes = false;
    if (verbose) {
      for (int i = 0; i < numRHS; ++i) {
        const double actRes = relativeResidualNorms[i];
        verbOut << "Problem " << i << " : \t" << actRes << endl;
        if (actRes > tol) {
          badRes = true;
        }
      }
    }

#   ifdef BELOS_TEUCHOS_TIME_MONITOR
    Teuchos::TimeMonitor::summarize (verbOut);
#   endif // BELOS_TEUCHOS_TIME_MONITOR

    success = (ret == Belos::Converged && !badRes);

    if (success) {
      verbOut << endl << "End Result: TEST PASSED" << endl;
    } else {
      verbOut << endl << "End Result: TEST FAILED" << endl;
    }
  } // try
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

  return success ? EXIT_SUCCESS : EXIT_FAILURE;
} // end test_minres_hb.cpp
int main(int argc, char* argv[])
{

  bool success = false;
  bool verbose = false;
  try
  {
    //
    // Open an output file stream for writing our XML file
    //
    std::ofstream out;
   
    //
    // We will print to the 'out' ofstream, and that output will be
    // valid XML describing the validated ParameterList.  For the
    // purposes of generating nicely-formatted HTML documentation for
    // this ParameterList, we also need to include an XSL header line.
    // This bool will control whether we include this header line,
    // which can be controlled at the command line.
    //
    bool xsl_header_flag = true;

    //
    // Set up the command line processor.  All versions of this
    // executable should support the add-xsl-header /
    // suppress-xsl-header command line options.  If you want a single
    // executable to support multiple ParameterLists, you could put
    // additional options here to control which ParameterList to
    // output.
    //
    CommandLineProcessor clp(false);  //don't throw exceptions
    clp.recogniseAllOptions(true);
    clp.setOption("add-xsl-header",
                  "suppress-xsl-header",
                  &xsl_header_flag, 
                  "XSL header flag");

    //
    // Parse the command line and quit if not successful
    //
    CommandLineProcessor::EParseCommandLineReturn parse_return =
      clp.parse(argc, argv);
    if(parse_return != CommandLineProcessor::PARSE_SUCCESSFUL)
      return parse_return;


    //
    // Here is where code should go that is required to generate the
    // validated XML file.  If your class uses a construct-then-init
    // idiom, then this is where the default constructor would be
    // called.  If this executable supports ParameterLists for more
    // than one class, then this is where the logic to pick the
    // appropriate class would go.
    //

	Belos::SolverFactory<scalar_type, multivector_type, operator_type> sFactory;
	RCP<solver_type> solver;
	for ( int i = 0; i < 4; ++i )
	{
		RCP<ParameterList> nullParams = parameterList();
		std::cout << "writing parameter list " << i+1 << " of 9." << std::endl;
		if ( i == 0 ) 
		{
			solver = sFactory.create("Block GMRES", nullParams);
			out.open("belos_BlockGmres.xml", std::ofstream::out);
			if ( xsl_header_flag )
				writeXSLHeader( out );
			RCP<const ParameterList> gmresParams = solver -> getValidParameters();
			Teuchos::writeParameterListToXmlOStream( *gmresParams, out);
			out.close();
		}
		else if ( i == 1 ) 	
		{
			solver = sFactory.create("Pseudo Block GMRES", nullParams);
			out.open("belos_PseudoBlockGmres.xml", std::ofstream::out);
			if ( xsl_header_flag )
				writeXSLHeader( out );
			RCP<const ParameterList> pseudoGmresParams = solver -> getValidParameters();
			Teuchos::writeParameterListToXmlOStream( *pseudoGmresParams, out);
			out.close();
		}
		else if ( i == 2 ) 
		{
			solver = sFactory.create("Block CG", nullParams);
			out.open("belos_BlockCG.xml", std::ofstream::out);
			if ( xsl_header_flag )
				writeXSLHeader( out );
			RCP<const ParameterList> blockCgParams = solver -> getValidParameters();
			Teuchos::writeParameterListToXmlOStream( *blockCgParams, out);
			out.close();
		}
		else if ( i == 3 ) 
		{
			solver = sFactory.create("Pseudo Block CG", nullParams);
			out.open("belos_PseudoBlockCG.xml", std::ofstream::out);
			if ( xsl_header_flag )
				writeXSLHeader( out );
			RCP<const ParameterList> pseudoBlockCgParams = solver -> getValidParameters();
			Teuchos::writeParameterListToXmlOStream( *pseudoBlockCgParams, out);
			out.close();
		}
	}

    success = true;
  }
  TEUCHOS_STANDARD_CATCH_STATEMENTS(verbose, std::cerr, success);

  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );

}
예제 #7
0
  void solve_system_hierarchy(Xpetra::UnderlyingLib & lib, RCP<Matrix> & A, RCP<Vector>&  X, RCP<Vector> & B, RCP<Hierarchy> & H, RCP<Teuchos::ParameterList> & SList) {
    using Teuchos::RCP;
    using Teuchos::rcp;
#ifdef HAVE_MUELU_BELOS
#ifdef HAVE_MUELU_TPETRA
    typedef Tpetra::Operator<SC,LO,GO> Tpetra_Operator;
    typedef Tpetra::CrsMatrix<SC,LO,GO> Tpetra_CrsMatrix;
    typedef Tpetra::Vector<SC,LO,GO> Tpetra_Vector;
    typedef Tpetra::MultiVector<SC,LO,GO> Tpetra_MultiVector;
    if(lib==Xpetra::UseTpetra) {
      RCP<Tpetra_CrsMatrix>   At = Xpetra::Helpers<SC,LO,GO>::Op2NonConstTpetraCrs(A);
      RCP<Tpetra_Operator>    Mt = rcp(new MueLu::TpetraOperator<SC,LO,GO>(H));
      RCP<Tpetra_MultiVector> Xt = Xpetra::toTpetra(*X);
      RCP<Tpetra_MultiVector> Bt = Xpetra::toTpetra(*B);
      typedef Tpetra_MultiVector MV;
      typedef Tpetra_Operator OP;
      RCP<Belos::LinearProblem<SC,MV,OP> > belosProblem = rcp(new Belos::LinearProblem<SC,MV,OP>(At, Xt, Bt));
      belosProblem->setRightPrec(Mt);
      belosProblem->setProblem(Xt,Bt);

      Belos::SolverFactory<SC, MV, OP> BelosFactory;
      Teuchos::RCP<Belos::SolverManager<SC, MV, OP> > BelosSolver = BelosFactory.create(std::string("CG"), SList);
      BelosSolver->setProblem(belosProblem);
      Belos::ReturnType result = BelosSolver->solve();
      if(result==Belos::Unconverged)
        throw std::runtime_error("Belos failed to converge");
    }
#endif
#if defined(HAVE_MUELU_EPETRA) and defined(HAVE_MUELU_SERIAL)
    if(lib==Xpetra::UseEpetra) {
      RCP<Epetra_CrsMatrix> Ae;
      // Get the underlying Epetra Mtx
      try {
        RCP<const Xpetra::CrsMatrixWrap<SC, LO, GO, Node> > crsOp = Teuchos::rcp_dynamic_cast<const Xpetra::CrsMatrixWrap<SC, LO, GO, Node> >(A);
        RCP<const Xpetra::CrsMatrix<SC, LO, GO, Node> > tmp_CrsMtx = crsOp->getCrsMatrix();
        const RCP<const Xpetra::EpetraCrsMatrixT<GO,Node> > &tmp_ECrsMtx = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO,Node> >(tmp_CrsMtx);
        if (tmp_ECrsMtx == Teuchos::null)
          throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::CrsMatrix to Xpetra::EpetraCrsMatrix failed"));
        const RCP<const Xpetra::EpetraCrsMatrixT<GO,Kokkos::Compat::KokkosSerialWrapperNode> > &tmp_ECrsMtxSer = Teuchos::rcp_dynamic_cast<const Xpetra::EpetraCrsMatrixT<GO,Kokkos::Compat::KokkosSerialWrapperNode> >(tmp_ECrsMtx);
        if (tmp_ECrsMtxSer == Teuchos::null)
          throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::EpetraCrsMatrix<...,Node> to Xpetra::EpetraCrsMatrix<...,Kokkos::Compat::KokkosSerialWrapperNode> failed"));
        //RCP<const Epetra_CrsMatrix> constEpMat = tmp_ECrsMtxSer->getEpetra_CrsMatrix();
        //Ae = Teuchos::rcp_const_cast<Epetra_CrsMatrix>(constEpMat);
        Ae = Teuchos::rcp_const_cast<Epetra_CrsMatrix>(tmp_ECrsMtxSer->getEpetra_CrsMatrix());
      } catch(...) {
        throw(Xpetra::Exceptions::BadCast("Cast from Xpetra::Matrix to Xpetra::CrsMatrixWrap failed"));
      }
      RCP<MueLu::Hierarchy<SC,LO,GO,Kokkos::Compat::KokkosSerialWrapperNode> > epH = Teuchos::rcp_dynamic_cast<MueLu::Hierarchy<SC,LO,GO,Kokkos::Compat::KokkosSerialWrapperNode> >(H);
      if (epH == Teuchos::null)
        throw(Xpetra::Exceptions::BadCast("Cast from MueLu::Hierarchy<...,Node> to MueLu::Hierarchy<...,Kokkos::Compat::KokkosSerialWrapperNode> failed"));
      RCP<MueLu::EpetraOperator> Me = rcp(new MueLu::EpetraOperator(epH));
      RCP<Epetra_MultiVector>    Xe = rcp(&Xpetra::toEpetra<GO,Node>(*X),false);
      RCP<Epetra_MultiVector>    Be = rcp(&Xpetra::toEpetra<GO,Node>(*B),false);
      typedef Epetra_MultiVector MV;
      typedef Epetra_Operator OP;
      RCP<Belos::LinearProblem<SC,MV,OP> > belosProblem = rcp(new Belos::LinearProblem<SC,MV,OP>(Ae, Xe, Be));
      Teuchos::RCP<Belos::EpetraPrecOp> PrecWrap = Teuchos::rcp(new Belos::EpetraPrecOp(Me));
      belosProblem->setRightPrec(PrecWrap);
      belosProblem->setProblem(Xe,Be);

      Belos::SolverFactory<SC, MV, OP> BelosFactory;
      Teuchos::RCP<Belos::SolverManager<SC, MV, OP> > BelosSolver = BelosFactory.create(std::string("CG"), SList);
      BelosSolver->setProblem(belosProblem);
      Belos::ReturnType result = BelosSolver->solve();
      if(result==Belos::Unconverged)
        throw std::runtime_error("Belos failed to converge");
    }
#endif
#endif // #ifdef HAVE_MUELU_BELOS
  }