Пример #1
0
  SolverState<double> PCGSolver::solve(const LinearOperator<double>& A,
				       const Vector<double>& b,
				       Vector<double>& x) const
  {
    if (precFactory_.ptr().get() == 0)
      {
	return solveUnprec(A, b, x);
      }
    else
      {
	SolverState<double> rtn;
	Preconditioner<double> prec = precFactory_.createPreconditioner(A);
	if (prec.isIdentity())
	  {
	    rtn = solveUnprec(A, b, x);
	  }
	else if (prec.isTwoSided())
	  {
	    LinearOperator<double> P = prec.left();
	    LinearOperator<double> Q = prec.right();
	    LinearOperator<double> PAQ = P*A*Q;
	    Vector<double> Pb = P*b;
	    Vector<double> y;
	    rtn = solveUnprec(PAQ, Pb, y);
	    x = Q*y;
	  }
	else if (prec.hasRight())
	  {
	    LinearOperator<double> Q = prec.right();
	    LinearOperator<double> AQ = A*Q;
	    Vector<double> y;
	    rtn = solveUnprec(AQ, b, y);
	    x = Q*y;
	  }
	else if (prec.hasLeft())
	  {
	    LinearOperator<double> P = prec.left();
	    LinearOperator<double> PA = P*A;
	    Vector<double> Pb = P*b;
	    rtn = solveUnprec(PA, Pb, x);
	  }
	else
	  {
	    TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
				       "Inconsistent preconditioner state "
				       "in PGCSolver::solve()");
	  }
	return rtn;
      }
  }
Пример #2
0
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, 
  const Vector<double>& rhs, 
  Vector<double>& soln) const
{
  typedef Anasazi::SimpleMV                      MV;
  typedef LinearOperator<double>                 OP;
  typedef Belos::LinearProblem<double, MV, OP>   LP;

  TEUCHOS_TEST_FOR_EXCEPT(!A.ptr().get());
  TEUCHOS_TEST_FOR_EXCEPT(!rhs.ptr().get());

  if (!soln.ptr().get()) 
  {
    soln = rhs.copy();
    /* KRL 8 Jun 2012: set x0 to zero to workaround bug in Belos */
    soln.zero();
  }

  if (rhs.norm2()==0.0)
  {
    soln.zero();
    SolverStatusCode code = SolveConverged;
    SolverState<double> state(code, "Detected trivial solution", 0, 0.0);
    
    return state;
  }


  RCP<OP> APtr = rcp(new LinearOperator<double>(A));
  RCP<MV> bPtr = rcp(new MV(1));
  (*bPtr)[0] = rhs;
  RCP<MV> ansPtr = rcp(new MV(1));
  (*ansPtr)[0] = soln;
  
  
  RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr));

  TEUCHOS_TEST_FOR_EXCEPT(!prob->setProblem());

  
  if (pf_.ptr().get())
  {
    Preconditioner<double> P = pf_.createPreconditioner(A);
    if (P.hasLeft())
    {
      prob->setLeftPrec(rcp(new OP(P.left())));
    }
  
    if (P.hasRight())
    {
      prob->setRightPrec(rcp(new OP(P.right())));
    }
  }

  if (!hasSolver_)
  {

    ParameterList plist = parameters();

    RCP<ParameterList> belosList = rcp(&plist, false);

    std::string solverType = parameters().get<string>("Method");
      
    if (solverType=="GMRES")
    {
      solver_=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="CG")
    {
      solver_=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="TFQMR")
    {
      solver_=rcp(new Belos::TFQMRSolMgr<double, MV, OP>(prob, belosList));
    }
    else if (solverType=="GCRODR")
    {
      solver_=rcp(new Belos::GCRODRSolMgr<double, MV, OP>(prob, belosList));
      hasSolver_ = true; // only cache recycling solvers
    }
    else if (solverType=="RCG")
    {
      solver_=rcp(new Belos::RCGSolMgr<double, MV, OP>(prob, belosList));
      hasSolver_ = true; // only cache recycling solvers
    }
    else
    {
      TEUCHOS_TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG"));
    }
  }
  else // reset problem
  {
    solver_->setProblem( prob );
  }
  
  Belos::ReturnType rtn = solver_->solve();

  int numIters = solver_->getNumIters();
  double resid = solver_->achievedTol();
  
  SolverStatusCode code = SolveFailedToConverge;
  if (rtn==Belos::Converged) code = SolveConverged;
  SolverState<double> state(code, "Belos solver completed", numIters, resid);
  
  return state;
}
Пример #3
0
SolverState<double> BelosSolver::solve(const LinearOperator<double>& A, 
  const Vector<double>& rhs, 
  Vector<double>& soln) const
{
  typedef Thyra::MultiVectorBase<double>         MV;
  typedef Thyra::LinearOpBase<double>            OP;
  typedef Belos::LinearProblem<double, MV, OP>   LP;

  TEST_FOR_EXCEPT(!A.ptr().get());
  TEST_FOR_EXCEPT(!rhs.ptr().get());

  /* get Thyra objects */
  RCP<OP> APtr = A.ptr();
  RCP<MV> bPtr = rhs.ptr(); 

  if (!soln.ptr().get()) soln = rhs.copy();

  RCP<MV> ansPtr = soln.ptr();

  
  
  RCP<LP> prob = rcp(new LP(APtr, ansPtr, bPtr));

  TEST_FOR_EXCEPT(!prob->setProblem());

  
  if (pf_.ptr().get())
  {
    Preconditioner<double> P = pf_.createPreconditioner(A);
    if (P.hasLeft())
    {
      prob->setLeftPrec(P.left().ptr());
    }
  
    if (P.hasRight())
    {
      prob->setRightPrec(P.right().ptr());
    }
  }

  ParameterList plist = parameters();

  RCP<ParameterList> belosList = rcp(&plist, false);
  RCP<Belos::SolverManager<double, MV, OP> > solver ;
  std::string solverType = parameters().get<string>("Method");
  
  if (solverType=="GMRES")
  {
    solver=rcp(new Belos::BlockGmresSolMgr<double, MV, OP>(prob, belosList));
  }
  else if (solverType=="CG")
  {
    solver=rcp(new Belos::BlockCGSolMgr<double, MV, OP>(prob, belosList));
  }
  else
  {
    TEST_FOR_EXCEPT(!(solverType=="GMRES" || solverType=="CG"));
  }

  Belos::ReturnType rtn = solver->solve();

  int numIters = solver->getNumIters();
  double resid = -1.0;
  
  SolverStatusCode code = SolveFailedToConverge;
  if (rtn==Belos::Converged) code = SolveConverged;
  SolverState<double> state(code, "Belos solver completed", numIters, resid);
  
  return state;
}