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);
    }
}
LinearOperator<double> epetraMatrixMatrixProduct(
  const LinearOperator<double>& A,
  const LinearOperator<double>& B)
{
  /* Extract the underlying Epetra matrix for A. Type checking is done
   * ny rcp_dynamic_cast, so we need no error check here. */
  RCP<const Epetra_CrsMatrix> A_crs = EpetraMatrix::getConcretePtr(A);

  /* Extract the underlying Epetra matrix for A. Type checking is done
   * ny rcp_dynamic_cast, so we need no error check here. */
  RCP<const Epetra_CrsMatrix> B_crs = EpetraMatrix::getConcretePtr(B);
  
  bool transA = false;
  bool transB = false;
  

  /* Get the row map from A. We will need this to build the target matrix C */
  const Epetra_Map* rowmap 
    = transA ? &(A_crs->DomainMap()) : &(A_crs->RowMap());

  /* make the target matrix */
  RCP<Epetra_CrsMatrix> C = rcp(new Epetra_CrsMatrix(Copy, *rowmap, 1));

  /* Carry out the multiplication */
  int ierr 
    = EpetraExt::MatrixMatrix::Multiply(*A_crs, transA, *B_crs, transB, *C);
  TEUCHOS_TEST_FOR_EXCEPTION(ierr != 0, RuntimeError,
    "EpetraExt Matrix-matrix multiply failed with error code ierr=" << ierr);

  /* Prepare an operator object for the scaled matrix */
  RCP<LinearOperatorBase<double> > rtn 
    = rcp(new EpetraMatrix(C, B.domain(), A.range()));
  return rtn;
  
}
Exemple #3
0
 /** 
  * Construct a InverseLTIOp that takes <t>numTimesteps</t> steps
  * with the operator \f$ A\f$.
  */
 InverseLTIOp(int numTimesteps, const LinearOperator<Scalar>& A,
   const LinearOperator<Scalar>& At)
   : HomogeneouslyBlockedLinearOp<Scalar>(
     A.domain(), numTimesteps,
     A.range(), numTimesteps),
     A_(A), At_(At)
   {}
Exemple #4
0
bool runit(const VectorType<double>& vecType,
           const LinearSolver<double>& solver)
{
    typedef Teuchos::ScalarTraits<double> ST;

    /* create the range space  */
    int nLocalRows = 10;

    MatrixLaplacian1D builder(nLocalRows, vecType);

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

    Out::root() << "matrix is " << std::endl;
    Out::os() << A << std::endl;

    Vector<double> x = A.domain().createMember();

    x.randomize();

    Out::root() << "input is " << std::endl;
    Out::os() << x << std::endl;
    Vector<double> y = A*x;

    Out::root() << "rhs is " << std::endl;
    Out::os() << y << std::endl;

    Vector<double> ans = A.range().createMember();

    Out::root() << "slot for solution is " << std::endl;
    Out::os() << ans << std::endl;

    LinearOperator<double> AInv = inverse(A, solver);

    ans = AInv * y;

    Out::root() << "answer is " << std::endl;
    Out::os() << ans << std::endl;

    double err = (x-ans).norm2();
    Out::root() << "error norm = " << err << std::endl;

    double tol = 1.0e-7;

    if (err <= tol)
    {
        Out::root() << "Poisson solve test PASSED" << std::endl;
        return true;
    }
    else
    {
        Out::root() << "Poisson solve test FAILED" << std::endl;
        return false;
    }
}
LinearOperator<double> epetraLeftScale(
  const Vector<double>& d,
  const LinearOperator<double>& A)
{
  /* Extract the underlying Epetra matrix. Type checking is done
   * ny rcp_dynamic_cast, so we need no error check here. */
  RCP<const Epetra_CrsMatrix> A_crs = EpetraMatrix::getConcretePtr(A);
  
  /* Make a deep copy of A */
  RCP<Epetra_CrsMatrix> mtxCopy = rcp(new Epetra_CrsMatrix(*A_crs));

  /* Extract the underlying Epetra vector. Type checking is done
   * internally, so we need no error check here. */
  const Epetra_Vector& epv = EpetraVector::getConcrete(d);
  
  /* Scale the copy */
  mtxCopy->LeftScale(epv);

  RCP<LinearOperatorBase<double> > rtn 
    = rcp(new EpetraMatrix(mtxCopy, A.domain(), A.range()));
  return rtn;
  
}
int main(int argc, char *argv[]) 
{
  typedef Teuchos::ScalarTraits<double> ST;

  try
  {
    GlobalMPISession session(&argc, &argv);

    MPIComm::world().synchronize();

    VectorType<double> type = new EpetraVectorType();


#ifdef HAVE_CONFIG_H
      ParameterXMLFileReader reader(Sundance::searchForFile("SolverParameters/userPrecParams.xml"));
#else
      ParameterXMLFileReader reader("userPrecParams.xml");
#endif

    ParameterList solverParams = reader.getParameters();
    ParameterList innerSolverParams = solverParams.sublist("Inner Solve");
    ParameterList outerSolverParams = solverParams.sublist("Outer Solve");

    /* create the range space  */
    int nLocalRows = solverParams.get<int>("nLocal");

    MatrixLaplacian1D builder(nLocalRows, type);

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

    Vector<double> x = A.domain().createMember();
    int myRank = MPIComm::world().getRank();
    int nProcs = MPIComm::world().getNProc();
      

    Thyra::randomize(-ST::one(),+ST::one(),x.ptr().ptr());
#ifdef TRILINOS_6
    if (myRank==0) x[0] = 0.0;
    if (myRank==nProcs-1) x[nProcs * nLocalRows - 1] = 0.0;
    // need to fix operator[] routine
#else
    if (myRank==0) x.setElement(0, 0);
    if (myRank==nProcs-1) x.setElement(nProcs * nLocalRows - 1, 0.0);
#endif

    cout << "x=" << std::endl;
    x.print(cout);
      
    Vector<double> y = A*x;
    cout << "y=" << std::endl;
    y.print(cout);

    Vector<double> ans = A.range().createMember();

    LinearSolver<double> innerSolver 
      = LinearSolverBuilder::createSolver(innerSolverParams);

    LinearSolver<double> outerSolver 
      = LinearSolverBuilder::createSolver(outerSolverParams);

    /* call the setUserPrec() function to set the operator and solver 
     * to be used for preconditioning */
    outerSolver.setUserPrec(A, innerSolver);

    LinearOperator<double> AInv = inverse(A, outerSolver);
      

    ans = AInv * y;

    //      SolverState<double> state = solver.solve(A, y, ans);
      

      
    //      cout << state << std::endl;

    cout << "answer is " << std::endl;
    ans.print(cout);
      
    double err = (x-ans).norm2();
    cout << "error norm = " << err << std::endl;

    double tol = 1.0e-8;
    if (err > tol)
    {
      cout << "User-defined preconditioner test FAILED" << std::endl;
      return 1;
    }
    else
    {
      cout << "User-defined preconditioner test PASSED" << std::endl;
      return 0;
    }
  }
  catch(std::exception& e)
  {
    cout << "Caught exception: " << e.what() << std::endl;
    return -1;
  }
}
Preconditioner<double> 
PCDPreconditionerFactory::
createPreconditioner(const LinearOperator<double>& K) const
{
  Tabs tab;

  LinearOperator<double> F = K.getBlock(0,0);
//  F.setName("F");
  LinearOperator<double> FInv = inverse(F, FSolver_);
//  FInv.setName("FInv");
  LinearOperator<double> Bt = K.getBlock(0,1);
//  Bt.setName("Bt");


  LinearOperator<double> Fp = FpProb_.getOperator();

  LinearOperator<double> Mp = MpProb_.getOperator();
//  Mp.setName("Mp");

  LinearOperator<double> MpInv = inverse(Mp, MpSolver_);
//  MpInv.setName("MpInv");

  LinearOperator<double> Ap = ApProb_.getOperator();
//  Ap.setName("Ap");

  LinearOperator<double> ApInv = inverse(Ap, ApSolver_);
//  ApInv.setName("ApInv");


  VectorSpace<double> pDomain = Bt.domain();
  VectorSpace<double> uDomain = F.domain();

  LinearOperator<double> Iu = identityOperator(uDomain);
//  Iu.setName("Iu");
  LinearOperator<double> Ip = identityOperator(pDomain);
//  Ip.setName("Ip");

  LinearOperator<double> XInv = MpInv * Fp * ApInv;

  VectorSpace<double> rowSpace = K.range();
  VectorSpace<double> colSpace = K.domain();
   
  LinearOperator<double> Q1 = makeBlockOperator(colSpace, rowSpace);
//  Q1.setName("Q1");
  LinearOperator<double> Q2 = makeBlockOperator(colSpace, rowSpace);
  // Q2.setName("Q2");
  LinearOperator<double> Q3 = makeBlockOperator(colSpace, rowSpace);
  //Q3.setName("Q3");
   
  Q1.setBlock(0, 0, FInv);
  Q1.setBlock(1, 1, Ip);
  Q1.endBlockFill();
   
  Q2.setBlock(0, 0, Iu);
  Q2.setBlock(0, 1, -1.0*Bt);
  Q2.setBlock(1, 1, Ip);
  Q2.endBlockFill();
   
  Q3.setBlock(0, 0, Iu);
  Q3.setBlock(1, 1, -1.0*XInv);
  Q3.endBlockFill();
   
  LinearOperator<double> P1 = Q2 * Q3;
  LinearOperator<double> PInv = Q1 * P1;

  return new GenericRightPreconditioner<double>(PInv);
}