예제 #1
0
//==============================================================================
int Ifpack2_Amesos::
ApplyInverse(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const
{

  if (IsComputed() == false)
    IFPACK2_CHK_ERR(-1);

  if (X.NumVectors() != Y.NumVectors())
    IFPACK2_CHK_ERR(-1); // wrong input
  
  Time_->ResetStartTime();

  // AztecOO gives X and Y pointing to the same memory location,
  // need to create an auxiliary vector, Xcopy
  Teuchos::RCP<const Tpetra_MultiVector> Xcopy;
  if (X.Pointers()[0] == Y.Pointers()[0])
    Xcopy = Teuchos::rcp( new Tpetra_MultiVector(X) );
  else
    Xcopy = Teuchos::rcp( &X, false );
    
  Problem_->SetLHS(&Y);
  Problem_->SetRHS((Tpetra_MultiVector*)Xcopy.get());
  IFPACK2_CHK_ERR(Solver_->Solve());

  ++NumApplyInverse_;
  ApplyInverseTime_ += Time_->ElapsedTime();

  return(0);
}
예제 #2
0
//==============================================================================
int Ifpack2_LocalFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X,
                               Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const
{

    // skip expensive checks, I suppose input data are ok

    Y.PutScalar(0.0);
    int NumVectors = Y.NumVectors();

    double** X_ptr;
    double** Y_ptr;
    X.ExtractView(&X_ptr);
    Y.ExtractView(&Y_ptr);

    for (int i = 0 ; i < NumRows_ ; ++i) {

        int Nnz;
        int ierr = Matrix_->ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,&Values_[0],
                                             &Indices_[0]);
        IFPACK2_CHK_ERR(ierr);

        for (int j = 0 ; j < Nnz ; ++j) {
            if (Indices_[j] < NumRows_ ) {
                for (int k = 0 ; k < NumVectors ; ++k)
                    Y_ptr[k][i] += Values_[j] * X_ptr[k][Indices_[j]];
            }
        }
    }

    return(0);
}
//==============================================================================
int Ifpack2_ReorderFilter::
Multiply(bool TransA, const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, 
         Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const
{
  // need two additional vectors
  Tpetra_MultiVector Xtilde(X.Map(),X.NumVectors());
  Tpetra_MultiVector Ytilde(Y.Map(),Y.NumVectors());
  // bring X back to original ordering
  Reordering_->Pinv(X,Xtilde);
  // apply original matrix
  IFPACK2_CHK_ERR(Matrix()->Multiply(TransA,Xtilde,Ytilde));
  // now reorder result
  Reordering_->P(Ytilde,Y);


  return(0);
}
예제 #4
0
//==============================================================================
int Ifpack2_AMDReordering::Pinv(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Xorig,
			       Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X) const
{
  int NumVectors = X.NumVectors();

  for (int j = 0 ; j < NumVectors ; ++j) {
    for (int i = 0 ; i < NumMyRows_ ; ++i) {
      int np = Reorder_[i];
      X[j][i] = Xorig[j][np];
    }
  }

  return(0);
}
예제 #5
0
//=============================================================================
// This function finds X such that LDU Y = X or U(trans) D L(trans) Y = X for multiple RHS
int Ifpack2_ILU::ApplyInverse(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, 
                             Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const
{

#ifdef ENABLE_IFPACK2_ILU_TEUCHOS_TIMERS
  TEUCHOS_FUNC_TIME_MONITOR("Ifpack2_ILU::ApplyInverse");
#endif

  if (!IsComputed())
    IFPACK2_CHK_ERR(-3);

  if (X.NumVectors() != Y.NumVectors())
    IFPACK2_CHK_ERR(-2);

  Time_.ResetStartTime();

  // AztecOO gives X and Y pointing to the same memory location,
  // need to create an auxiliary vector, Xcopy
  Teuchos::RCP< const Tpetra_MultiVector > Xcopy;
  if (X.Pointers()[0] == Y.Pointers()[0])
    Xcopy = Teuchos::rcp( new Tpetra_MultiVector(X) );
  else
    Xcopy = Teuchos::rcp( &X, false );

  IFPACK2_CHK_ERR(Solve(Ifpack2_ILU::UseTranspose(), *Xcopy, Y));

  // approx is the number of nonzeros in L and U
  ApplyInverseFlops_ += X.NumVectors() * 4 * 
    (L_->NumGlobalNonzeros() + U_->NumGlobalNonzeros());

  ++NumApplyInverse_;
  ApplyInverseTime_ += Time_.ElapsedTime();

  return(0);

}
/*
//old Apply (no communication)
int Ifpack2_NodeFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X,
	  Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const 
{

  // skip expensive checks, I suppose input data are ok

  Y.PutScalar(0.0);
  int NumVectors = Y.NumVectors();

  double** X_ptr;
  double** Y_ptr;
  X.ExtractView(&X_ptr);
  Y.ExtractView(&Y_ptr);

  for (int i = 0 ; i < NumRows_ ; ++i) {
    
    int Nnz;
    int ierr = Matrix_->ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,&Values_[0],
                                         &Indices_[0]);
    IFPACK2_CHK_ERR(ierr);

    for (int j = 0 ; j < Nnz ; ++j) {
      if (Indices_[j] < NumRows_ ) {
	for (int k = 0 ; k < NumVectors ; ++k)
	  Y_ptr[k][i] += Values_[j] * X_ptr[k][Indices_[j]];
      }
    }
  }

  return(0);
}
*/
int Ifpack2_NodeFilter::Apply(const Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& X, Tpetra_MultiVector<Scalar,LocalOrdinal,GlobalOrdinal,Node>& Y) const {
  //
  // This function forms the product Y = A * X.
  //

  int NumEntries;

  int NumVectors = X.NumVectors();
  if (NumVectors!=Y.NumVectors()) {
    EPETRA_CHK_ERR(-1); // Need same number of vectors in each MV
  }

  // Make sure Import and Export Vectors are compatible
  UpdateImportVector(NumVectors);
  UpdateExportVector(NumVectors);

  double ** Xp = (double**) X.Pointers();
  double ** Yp = (double**) Y.Pointers();


  // If we have a non-trivial importer, we must import elements that are permuted or are on other processors
  if (Importer()!=0) {
    EPETRA_CHK_ERR(ImportVector_->Import(X, *Importer(), Insert));
    Xp = (double**)ImportVector_->Pointers();
  }

  // If we have a non-trivial exporter, we must export elements that are permuted or belong to other processors
  if (Exporter()!=0) {
    Yp = (double**)ExportVector_->Pointers();
  }

  // Do actual computation
  assert(ovA_!=0);
  int *MyRows;
  double *MyValues;
  int *MyIndices;

  if(Acrs_){
    // A rows - CrsMatrix Case
    IFPACK2_CHK_ERR(Acrs_->ExtractCrsDataPointers(MyRows,MyIndices,MyValues));
    //special case NumVectors==1
    if (NumVectors==1) {
      for(int i=0;i<NumMyRowsA_;i++) {
        int LocRow=Ar_LIDMap_[i];
        double sum = 0.0;
        for(int j = MyRows[i]; j < MyRows[i+1]; j++)
          sum += MyValues[j]*Xp[0][Ac_LIDMap_[MyIndices[j]]];          
        Yp[0][LocRow] = sum;
      }
    }
    else {
      for(int i=0;i<NumMyRowsA_;i++) {
        int LocRow=Ar_LIDMap_[i];
        for (int k=0; k<NumVectors; k++) {
          double sum = 0.0;
          for(int j = MyRows[i]; j < MyRows[i+1]; j++)
            sum += MyValues[j]*Xp[k][Ac_LIDMap_[MyIndices[j]]];          
          Yp[k][LocRow] = sum;
        }
      }
    }
  }
  else{
    // A rows - RowMatrix Case
    MyValues=&Values_[0];
    MyIndices=&Indices_[0];
    for(int i=0;i<NumMyRowsA_;i++) {
      ovA_->A().ExtractMyRowCopy(i,MaxNumEntries_,NumEntries,MyValues,MyIndices);
      int LocRow=Ar_LIDMap_[i];
      for (int k=0; k<NumVectors; k++) {
        double sum = 0.0;
        for(int j = 0; j < NumEntries; j++)
        sum += MyValues[j]*Xp[k][Ac_LIDMap_[MyIndices[j]]];          
        Yp[k][LocRow] = sum;
      }
    }
  }

  // B rows, always CrsMatrix
  IFPACK2_CHK_ERR(ovA_->B().ExtractCrsDataPointers(MyRows,MyIndices,MyValues));
  //special case NumVectors==1
  if (NumVectors==1) {
    for(int i=0;i<NumMyRowsB_;i++) {
      int LocRow=Br_LIDMap_[i];
      double sum = 0.0;
      for(int j = MyRows[i]; j < MyRows[i+1]; j++)
        sum += MyValues[j]*Xp[0][Bc_LIDMap_[MyIndices[j]]];          
      Yp[0][LocRow] = sum;
    }
  } else {
    for(int i=0;i<NumMyRowsB_;i++) {
      int LocRow=Br_LIDMap_[i];
      for (int k=0; k<NumVectors; k++) { //FIXME optimization, check for NumVectors=1
        double sum = 0.0;
        for(int j = MyRows[i]; j < MyRows[i+1]; j++)
          sum += MyValues[j]*Xp[k][Bc_LIDMap_[MyIndices[j]]];          
        Yp[k][LocRow] = sum;
      }
    }
  }

  if (Exporter()!=0) {
    Y.PutScalar(0.0);  // Make sure target is zero
    Y.Export(*ExportVector_, *Exporter(), Add); // Fill Y with Values from export vector
  }
  // Handle case of rangemap being a local replicated map
  if (!OperatorRangeMap().DistributedGlobal() && Comm().NumProc()>1) EPETRA_CHK_ERR(Y.Reduce());

  return(0);
} //Apply