Пример #1
0
//==============================================================================
int Ifpack_Chebyshev::
PowerMethod(const Epetra_Operator& Operator, 
            const Epetra_Vector& InvPointDiagonal, 
            const int MaximumIterations, 
            double& lambda_max)
{
  // this is a simple power method
  lambda_max = 0.0;
  double RQ_top, RQ_bottom, norm;
  Epetra_Vector x(Operator.OperatorDomainMap());
  Epetra_Vector y(Operator.OperatorRangeMap());
  x.Random();
  x.Norm2(&norm);
  if (norm == 0.0) IFPACK_CHK_ERR(-1);

  x.Scale(1.0 / norm);

  for (int iter = 0; iter < MaximumIterations; ++iter)
  {
    Operator.Apply(x, y);
    IFPACK_CHK_ERR(y.Multiply(1.0, InvPointDiagonal, y, 0.0));
    IFPACK_CHK_ERR(y.Dot(x, &RQ_top));
    IFPACK_CHK_ERR(x.Dot(x, &RQ_bottom));
    lambda_max = RQ_top / RQ_bottom;
    IFPACK_CHK_ERR(y.Norm2(&norm));
    if (norm == 0.0) IFPACK_CHK_ERR(-1);
    IFPACK_CHK_ERR(x.Update(1.0 / norm, y, 0.0));
  }

  return(0);
}
// ============================================================================ 
ML_Epetra::MatrixFreePreconditioner::
MatrixFreePreconditioner(const Epetra_Operator& Operator,
                         const Epetra_CrsGraph& Graph,
                         Epetra_MultiVector& NullSpace,
                         const Epetra_Vector& PointDiagonal,
                         Teuchos::ParameterList& List) :
  verbose_(false),
  Comm_ML_(0),
  Comm_(Operator.Comm()),
  Label_("ML matrix-free preconditioner"),
  IsComputed_(false),
  PrecType_(ML_MFP_HYBRID),
  SmootherType_(ML_MFP_BLOCK_JACOBI),
  omega_(1.00),
  Operator_(Operator),
  C_ML_(0),
  NumPDEEqns_(0),
  NumMyBlockRows_(0)
{
  InvPointDiagonal_ = rcp(new Epetra_Vector(PointDiagonal));

  List_ = List;

  // ML communicator, here based on MPI_COMM_WORLD
  ML_Comm_Create(&Comm_ML_);
#ifdef ML_MPI
  const Epetra_MpiComm *epcomm = dynamic_cast<const Epetra_MpiComm*>(&(Operator.Comm()));
  // Get the MPI communicator, as it may not be MPI_COMM_W0RLD, and update the ML comm object
  if (epcomm) ML_Comm_Set_UsrComm(Comm_ML_,epcomm->Comm());
#endif

  Time_ = rcp(new Epetra_Time(Comm()));

  ML_CHK_ERRV(Compute(Graph, NullSpace));
}
// ============================================================================ 
bool ML_Epetra::MatrixFreePreconditioner::
CheckSPD(const Epetra_Operator& A, const bool UseApply,
         const int NumChecks, 
         const int NumVectors) const
{
  bool res = true;
  std::vector<double> norm(NumVectors);

  if (!IsComputed())
    return(false);

  if (MyPID() == 0)
    std::cout << "Checking SPD property of the operator... " << std::endl;

  Epetra_MultiVector X(A.OperatorDomainMap(), NumVectors);
  Epetra_MultiVector AX(A.OperatorRangeMap(), NumVectors);

  try
  {
    for (int i = 0; i < NumChecks; ++i)
    {
      int ierr;

      if (X.Random()) res = false;
      if (UseApply)
        ierr = A.Apply(X, AX);
      else
        ierr = A.ApplyInverse(X, AX);

      if (ierr < 0)
        throw(-1);

      AX.Dot(X, &norm[0]);

      for (int v = 0; v < NumVectors; ++v)
      {
        std::cout << norm[v] << std::endl;
        if (norm[v] <= 0.0)
          throw(-2);
      }
    }
  }
  catch(...)
  {
    res = false;
  }

  if (MyPID() == 0)
  {
    if (res)
      std::cout << "Passed: all x * A * x are positive." << std::endl;
    else
      std::cout << "Failed: some  x * A * x are negative or zero!" << std::endl;
  }

  return(res);
}
Пример #4
0
void StratimikosFactory::buildStridedVectors(const Epetra_Operator & Jac,
                                             const std::vector<int> & decomp,
                                             std::vector<std::vector<int> > & vars) const
{
   const Epetra_Map & rangeMap = Jac.OperatorRangeMap();

   // compute total number of variables
   int numVars = 0;
   for(std::size_t i=0;i<decomp.size();i++)
      numVars += decomp[i];

   // verify that the decomposition is appropriate for this matrix
   TEUCHOS_ASSERT((rangeMap.NumMyElements() % numVars)==0);
   TEUCHOS_ASSERT((rangeMap.NumGlobalElements() % numVars)==0);
  
   int * globalIds = rangeMap.MyGlobalElements();

   vars.resize(decomp.size());
   for(int i=0;i<rangeMap.NumMyElements();) {

      // for each "node" copy global ids to vectors
      for(std::size_t d=0;d<decomp.size();d++) {
         // for this variable copy global ids to variable arrays
         int current = decomp[d];
         for(int v=0;v<current;v++,i++)
            vars[d].push_back(globalIds[i]);
      }
   }
}
Пример #5
0
//==============================================================================
int Ifpack_Chebyshev::
CG(const Epetra_Operator& Operator,
   const Epetra_Vector& InvPointDiagonal,
   const int MaximumIterations,
   double& lambda_min, double& lambda_max,const unsigned int * RngSeed)
{
#ifdef HAVE_IFPACK_AZTECOO
  Epetra_Vector x(Operator.OperatorDomainMap());
  Epetra_Vector y(Operator.OperatorRangeMap());
  if(RngSeed) x.SetSeed(*RngSeed);
  x.Random();
  y.PutScalar(0.0);

  Epetra_LinearProblem LP(const_cast<Epetra_Operator*>(&Operator), &x, &y);
  AztecOO solver(LP);
  solver.SetAztecOption(AZ_solver, AZ_cg_condnum);
  solver.SetAztecOption(AZ_output, AZ_none);

  Ifpack_DiagPreconditioner diag(Operator.OperatorDomainMap(),
                                 Operator.OperatorRangeMap(),
                                 InvPointDiagonal);
  solver.SetPrecOperator(&diag);
  solver.Iterate(MaximumIterations, 1e-10);

  const double* status = solver.GetAztecStatus();

  lambda_min = status[AZ_lambda_min];
  lambda_max = status[AZ_lambda_max];

  return(0);
#else
  using std::cout;
  using std::endl;

  cout << "You need to configure IFPACK with support for AztecOO" << endl;
  cout << "to use the CG estimator. This may require --enable-aztecoo" << endl;
  cout << "in your configure script." << endl;
  IFPACK_CHK_ERR(-1);
#endif
}
Пример #6
0
int runOperatorTests(Epetra_Operator & A, bool verbose) {

  int ierr = 0;


  double residual;
  EPETRA_CHK_ERR(EpetraExt::OperatorToMatrixMarketFile("Test_A1.mm", A, "Official EpetraExt test operator", 
							"This is the official EpetraExt test operator generated by the EpetraExt regression tests"));
  EPETRA_CHK_ERR(EpetraExt::OperatorToMatlabFile("Test_A1.dat", A));

  A.OperatorRangeMap().Comm().Barrier();
  A.OperatorRangeMap().Comm().Barrier();
  Epetra_CrsMatrix * A1; 
  Epetra_CrsMatrix * A2; 
  EPETRA_CHK_ERR(EpetraExt::MatrixMarketFileToCrsMatrix("Test_A1.mm", A.OperatorRangeMap(), A1));
  EPETRA_CHK_ERR(EpetraExt::MatlabFileToCrsMatrix("Test_A1.dat", A.OperatorRangeMap().Comm(), A2));


  residual = A.NormInf(); double rAInf = residual;
  if (verbose) std::cout << "Inf Norm of Operator A                                            = " << residual << std::endl;
  residual = A1->NormInf(); double rA1Inf = residual;
  if (verbose) std::cout << "Inf Norm of Matrix A1                                             = " << residual << std::endl;
  ierr += checkValues(rA1Inf,rAInf,"Inf Norm of A", verbose);


  Epetra_Vector x(A.OperatorDomainMap()); x.Random();
  Epetra_Vector y1(A.OperatorRangeMap());
  Epetra_Vector y2(A.OperatorRangeMap());
  Epetra_Vector y3(A.OperatorRangeMap());
  A.Apply(x,y1);
  A1->Multiply(false, x, y2);
  A2->Multiply(false, x, y3);

  y1.Norm2(&residual); double rAx1 = residual;
  if (verbose) std::cout << "Norm of A*x                                                       = " << residual << std::endl;

  y2.Norm2(&residual); double rAx2 = residual;
  if (verbose) std::cout << "Norm of A1*x                                                      = " << residual << std::endl;
  ierr += checkValues(rAx1,rAx2,"Norm of A1*x", verbose);

  y3.Norm2(&residual); double rAx3 = residual;
  if (verbose) std::cout << "Norm of A2*x                                                      = " << residual << std::endl;
  ierr += checkValues(rAx1,rAx3,"Norm of A2*x", verbose);

  delete A1;
  delete A2;

  return(ierr);
}
Пример #7
0
//==============================================================================
int Ifpack_Polynomial::
GMRES(const Epetra_Operator& Operator,
      const Epetra_Vector& InvPointDiagonal,
      const int MaximumIterations,
      double& lambda_real_min, double& lambda_real_max,
      double& lambda_imag_min, double& lambda_imag_max)
{
#ifdef HAVE_IFPACK_AZTECOO
  Epetra_Vector x(Operator_->OperatorDomainMap());
  Epetra_Vector y(Operator_->OperatorRangeMap());
  x.Random();
  y.PutScalar(0.0);
  Epetra_LinearProblem LP(const_cast<Epetra_RowMatrix*>(&*Matrix_), &x, &y);
  AztecOO solver(LP);
  solver.SetAztecOption(AZ_solver, AZ_gmres_condnum);
  solver.SetAztecOption(AZ_output, AZ_none);
  Ifpack_DiagPreconditioner diag(Operator.OperatorDomainMap(),
                                 Operator.OperatorRangeMap(),
                                 InvPointDiagonal);
  solver.SetPrecOperator(&diag);
  solver.Iterate(MaximumIterations, 1e-10);
  const double* status = solver.GetAztecStatus();
  lambda_real_min = status[AZ_lambda_real_min];
  lambda_real_max = status[AZ_lambda_real_max];
  lambda_imag_min = status[AZ_lambda_imag_min];
  lambda_imag_max = status[AZ_lambda_imag_max];
  return(0);
#else
  using std::cout;
  using std::endl;

  cout << "You need to configure IFPACK with support for AztecOO" << endl;
  cout << "to use the GMRES estimator. This may require --enable-aztecoo" << endl;
  cout << "in your configure script." << endl;
  IFPACK_CHK_ERR(-1);
#endif
}
Teuchos::RCP<Epetra_CrsMatrix> Epetra_Operator_to_Epetra_Matrix::constructInverseMatrix(const Epetra_Operator &op, const Epetra_Map &map)
{
  int numEntriesPerRow = 0;
  Teuchos::RCP<Epetra_FECrsMatrix> matrix = Teuchos::rcp(new Epetra_FECrsMatrix(::Copy, map, numEntriesPerRow));

  int numRows = map.NumGlobalElements();

  Epetra_Vector X(map);
  Epetra_Vector Y(map);

  double tol = 1e-15; // values below this will be considered 0

  for (int rowIndex=0; rowIndex<numRows; rowIndex++)
  {
    int lid = map.LID(rowIndex);
    if (lid != -1)
    {
      X[lid] = 1.0;
    }
    op.ApplyInverse(X, Y);
    if (lid != -1)
    {
      X[lid] = 0.0;
    }

    std::vector<double> values;
    std::vector<int> indices;
    for (int i=0; i<map.NumMyElements(); i++)
    {
      if (abs(Y[i]) > tol)
      {
        values.push_back(Y[i]);
        indices.push_back(map.GID(i));
      }
    }

    matrix->InsertGlobalValues(rowIndex, values.size(), &values[0], &indices[0]);
  }

  matrix->GlobalAssemble();
  return matrix;
}