示例#1
0
Epetra_TSFOperator::Epetra_TSFOperator(const LinearOperator<double>& A,
				       const LinearSolver<double>& solver)
  : A_(A), solver_(solver), useTranspose_(false), comm_(), domain_(), range_(),
    isNativeEpetra_(false), isCompoundEpetra_(false), label_(A.description())
{
  const EpetraMatrix* em = dynamic_cast<const EpetraMatrix*>(A.ptr().get());
  const EpetraVectorSpace* ed = dynamic_cast<const EpetraVectorSpace*>(A.domain().ptr().get());
  const EpetraVectorSpace* er = dynamic_cast<const EpetraVectorSpace*>(A.range().ptr().get());

  if (em)
    {
      isNativeEpetra_ = true;
      const Epetra_CrsMatrix* crs = em->crsMatrix();
      domain_ = rcp(new Epetra_Map(crs->OperatorDomainMap()));
      range_ = rcp(new Epetra_Map(crs->OperatorRangeMap()));
      useTranspose_ = crs->UseTranspose();
      comm_ = rcp(crs->Comm().Clone());
    }
  else if (er != 0 && ed != 0)
    {
      domain_ = ed->epetraMap();
      range_ = er->epetraMap();
      comm_ = rcp(domain_->Comm().Clone());
      isCompoundEpetra_ = true;
    }
  else
    {
      TEST_FOR_EXCEPT(true);
    }
}
    virtual Preconditioner <Scalar>
    createPreconditioner(const LinearOperator<Scalar>& A) const 
    {
      /* In order for ICC factorization to work, the operator A must
       * implement the ICCFactorizableOp interface. We cast A's pointer
       * to a ICCFactorizableOp ptr. If the cast fails, throw a spoke. */
      
      const ICCFactorizableOp<Scalar>* fop 
        = dynamic_cast<const ICCFactorizableOp<Scalar>*>(A.ptr().get());

      TEUCHOS_TEST_FOR_EXCEPTION(fop==0, std::runtime_error,
                         "ICCPreconditionerFactory attempted to "
                         "create an ICC preconditioner for an operator type "
                         "that does not implement the ICCFactorizableOp "
                         "interface. The op is " << A.description());

      
      /* Now we can delegate the construction of the ICC factors to 
      * the factorizable op. */
      Preconditioner<Scalar> P;
      fop->getICCPreconditioner(fillLevels_,
                                 overlapFill_,
                                 relaxationValue_,
                                 relativeThreshold_,
                                 absoluteThreshold_,
                                 P);
      /* Return the preconditioner */
      return P;
    }
 LinearOperator<double> createW() const 
 {
   static LinearOperator<double> J = prob_.allocateJacobian();
   TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError,
                      "null Jacobian");
   return J;
 }
示例#4
0
void NLOp::
computeJacobianAndFunction(LinearOperator<double>& J,
  Vector<double>& resid) const
{
  /* Set the vector underlying the discrete 
   * function to the evaluation point*/

  TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
    "null discrete function pointer in "
    "NLOp::jacobian()");

  TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
    "null evaluation point in "
    "NLOp::jacobian()");

  TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError,
    "null Jacobian pointer in "
    "NLOp::jacobian()");

  TEST_FOR_EXCEPTION(resid.ptr().get()==0, RuntimeError,
    "null residual pointer in "
    "NLOp::jacobian()");

  discreteU0_->setVector(currentEvalPt());

  Array<Vector<double> > mv(1);
  mv[0] = resid;

  assembler_->assemble(J, mv);

  resid.acceptCopyOf(mv[0]);

  J_ = J;
}
示例#5
0
int main(int argc, char *argv[]) 
{
  int stat = 0;
  try
  {
    GlobalMPISession session(&argc, &argv);
    MPIComm::world().synchronize();

    Out::os() << "go!" << std::endl;
    VectorType<double> type = new EpetraVectorType();

    Array<int> domainBlockSizes = tuple(2,3,4);
    Array<int> rangeBlockSizes = tuple(2,2);

    Array<VectorSpace<double> > domainBlocks(domainBlockSizes.size());
    Array<VectorSpace<double> > rangeBlocks(rangeBlockSizes.size());

    for (int i=0; i<domainBlocks.size(); i++)
    {
      domainBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        domainBlockSizes[i]);
    }

    for (int i=0; i<rangeBlocks.size(); i++)
    {
      rangeBlocks[i] = type.createEvenlyPartitionedSpace(MPIComm::world(),
        rangeBlockSizes[i]);
    }
      
    VectorSpace<double> domain = blockSpace(domainBlocks);
    VectorSpace<double> range = blockSpace(rangeBlocks);

    double blockDensity = 0.75;
    double onProcDensity = 0.5;
    double offProcDensity = 0.1;
      
    RandomBlockMatrixBuilder<double> builder(domain, range, 
      blockDensity,
      onProcDensity,
      offProcDensity,
      type);

    LinearOperator<double> A = builder.getOp();

    Out::os() << "A num block rows = " << A.numBlockRows() << std::endl;
    Out::os() << "A num block cols = " << A.numBlockCols() << std::endl;

    Vector<double> x = domain.createMember();
    Out::os() << "randomizing trial vector" << std::endl;
    x.randomize();

    Array<Vector<double> > xBlock(domain.numBlocks());
    for (int i=0; i<xBlock.size(); i++)
    {
      xBlock[i] = x.getBlock(i);
    }

    Vector<double> xx = x.copy();

      

    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x..." << std::endl;
    Vector<double> y0 = A * x;
    for (int i=0; i<y0.space().numBlocks(); i++)
    {
      Out::os() << "y0[" << i << "] = " << std::endl << y0.getBlock(i) << std::endl;
    }
      

    Vector<double> y1 = range.createMember();
    Out::os() << "------------------------------------------------------------" << std::endl;
    Out::os() << "computing A*x block-by-block..." << std::endl;
    Array<Vector<double> > yBlock(range.numBlocks());
    for (int i=0; i<yBlock.size(); i++)
    {
      yBlock[i] = range.getBlock(i).createMember();
      yBlock[i].zero();
      for (int j=0; j<xBlock.size(); j++)
      {
        LinearOperator<double> Aij = A.getBlock(i,j);
        if (Aij.ptr().get() != 0)
        {
          Out::os() << "A(" << i << ", " << j << ") = " << std::endl 
                    << Aij << std::endl;
        }
        else
        {
          Out::os() << "A(" << i << ", " << j << ") = 0 " << std::endl;
        }
        Out::os() << "x[" << j << "] = " << std::endl << xBlock[j] << std::endl;
        if (Aij.ptr().get()==0) continue;
        yBlock[i] = yBlock[i] + Aij * xBlock[j];
      }
      y1.setBlock(i, yBlock[i]);
    }

    for (int i=0; i<y1.space().numBlocks(); i++)
    {
      Out::os() << "y1[" << i << "] = " << std::endl << y1.getBlock(i) << std::endl;
    }
    double err = (y1 - y0).norm2();
    Out::os() << "error = " << err << std::endl;

    double tol = 1.0e-13;
    if (err < tol)
    {
      Out::os() << "block op test PASSED" << std::endl;
    }
    else
    {
      stat = -1;
      Out::os() << "block op test FAILED" << std::endl;
    }
  }
  catch(std::exception& e)
  {
    stat = -1;
    Out::os() << "Caught exception: " << e.what() << std::endl;
  }
  return stat;
}
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;
}
示例#7
0
int main(int argc, char *argv[]) 
{
  int stat = 0;
  try
    {
      GlobalMPISession session(&argc, &argv);

      VectorType<double> vecType = new SerialVectorType();

      VectorSpace<double> domain 
        = vecType.createEvenlyPartitionedSpace(MPIComm::world(), 3);
      VectorSpace<double> range
        = vecType.createEvenlyPartitionedSpace(MPIComm::world(), 5);

      RCP<MatrixFactory<double> > mf 
        = vecType.createMatrixFactory(domain, range);

      LinearOperator<double> A = mf->createMatrix();
      RCP<DenseSerialMatrix> APtr 
        = rcp_dynamic_cast<DenseSerialMatrix>(A.ptr());

      APtr->setRow(0, tuple(1.0,   2.0,  3.0));
      APtr->setRow(1, tuple(4.0,   5.0,  6.0));
      APtr->setRow(2, tuple(7.0,   8.0,  9.0));
      APtr->setRow(3, tuple(10.0, 11.0,  12.0));
      APtr->setRow(4, tuple(13.0, 14.0,  15.0));

      Out::os() << "A = " << std::endl;
      A.setVerb(10);
      Out::os() << A << std::endl;

      LinearOperator<double> U;
      LinearOperator<double> Vt;
      Vector<double> sigma;

      denseSVD(A, U, sigma, Vt);

      Out::os() << "U = " << std::endl;
      U.setVerb(10);
      Out::os() << U << std::endl;

      Out::os() << "sigma = " << std::endl;
      Out::os() << sigma << std::endl; 

      Out::os() << "Vt = " << std::endl;
      Vt.setVerb(10);
      Out::os() << Vt << std::endl;

      int nSamples = 10;
      bool allOK = true;
      double tol = 1.0e-13;
      for (int i=0; i<nSamples; i++)
      {
        Out::os() << "Sample #" << i << " of " << nSamples << std::endl;
        Vector<double> x = domain.createMember();
        x.randomize();
        
        U.setVerb(0);
        Vt.setVerb(0);
        A.setVerb(0);
        
        LinearOperator<double> Sigma = diagonalOperator(sigma);
        
        Vector<double> z = (U * Sigma * Vt)*x - A*x;
        double ez = z.norm2();
        Out::os() << "|| (U Sigma Vt - A)*x || = " << ez << std::endl;
        
        Vector<double> y = (U.transpose() * U)*x - x;
        double ey = y.norm2();
        Out::os() << "|| (U^T U - I)*x || = " << ey << std::endl;
        
        Vector<double> w = (Vt * Vt.transpose())*x - x;
        double ew = w.norm2();
        Out::os() << "|| (V^T*V - I)*x || = " << ew << std::endl;
        if (ew > tol || ez > tol || ey > tol) allOK = false;
      }

      if (allOK)
      {
        Out::os() << "SVD test PASSED" << std::endl;
      }
      else
      {
        Out::os() << "SVD test FAILED" << std::endl;
        stat = -1;
      }

      
    }
  catch(std::exception& e)
    {
      stat = -1;
      Out::os() << "Caught exception: " << e.what() << std::endl;
    }
  return stat;
}
示例#8
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;
}