Exemplo n.º 1
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);
}
/*
//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