00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "Ifpack_ConfigDefs.h"
00031
00032 #include "Epetra_MultiVector.h"
00033 #include "Epetra_Vector.h"
00034 #include "Epetra_RowMatrix.h"
00035 #include "Epetra_Map.h"
00036 #include "Epetra_BlockMap.h"
00037 #include "Ifpack_LocalFilter.h"
00038
00039
00040 Ifpack_LocalFilter::Ifpack_LocalFilter(const Teuchos::RefCountPtr<const Epetra_RowMatrix>& Matrix) :
00041 Matrix_(Matrix),
00042 NumRows_(0),
00043 NumNonzeros_(0),
00044 MaxNumEntries_(0),
00045 MaxNumEntriesA_(0)
00046 {
00047 sprintf(Label_,"%s","Ifpack_LocalFilter");
00048
00049 #ifdef HAVE_MPI
00050 SerialComm_ = Teuchos::rcp( new Epetra_MpiComm(MPI_COMM_SELF) );
00051 #else
00052 SerialComm_ = Teuchos::rcp( new Epetra_SerialComm );
00053 #endif
00054
00055
00056 NumRows_ = Matrix->NumMyRows();
00057
00058
00059 Map_ = Teuchos::rcp( new Epetra_Map(NumRows_,0,*SerialComm_) );
00060
00061
00062
00063
00064 NumEntries_.resize(NumRows_);
00065
00066
00067 Diagonal_ = Teuchos::rcp( new Epetra_Vector(*Map_) );
00068 if (Diagonal_ == Teuchos::null) IFPACK_CHK_ERRV(-5);
00069
00070
00071
00072 MaxNumEntriesA_ = Matrix->MaxNumEntries();
00073
00074
00075 MaxNumEntries_ = Matrix->MaxNumEntries();
00076
00077
00078 Indices_.resize(MaxNumEntries_);
00079 Values_.resize(MaxNumEntries_);
00080
00081
00082
00083
00084
00085
00086
00087
00088 int ActualMaxNumEntries = 0;
00089
00090 for (int i = 0 ; i < NumRows_ ; ++i) {
00091
00092 NumEntries_[i] = 0;
00093 int Nnz, NewNnz = 0;
00094 IFPACK_CHK_ERRV(ExtractMyRowCopy(i,MaxNumEntries_,Nnz,&Values_[0],&Indices_[0]));
00095
00096 for (int j = 0 ; j < Nnz ; ++j) {
00097 if (Indices_[j] < NumRows_ ) ++NewNnz;
00098
00099 if (Indices_[j] == i)
00100 (*Diagonal_)[i] = Values_[j];
00101 }
00102
00103 if (NewNnz > ActualMaxNumEntries)
00104 ActualMaxNumEntries = NewNnz;
00105
00106 NumNonzeros_ += NewNnz;
00107 NumEntries_[i] = NewNnz;
00108
00109 }
00110
00111 MaxNumEntries_ = ActualMaxNumEntries;
00112 }
00113
00114
00115 int Ifpack_LocalFilter::
00116 ExtractMyRowCopy(int MyRow, int Length, int & NumEntries,
00117 double *Values, int * Indices) const
00118 {
00119 if ((MyRow < 0) || (MyRow >= NumRows_)) {
00120 IFPACK_CHK_ERR(-1);
00121 }
00122
00123 if (Length < NumEntries_[MyRow])
00124 return(-1);
00125
00126
00127
00128
00129 int Nnz;
00130 int ierr = Matrix_->ExtractMyRowCopy(MyRow,MaxNumEntriesA_,Nnz,
00131 &Values_[0],&Indices_[0]);
00132
00133 IFPACK_CHK_ERR(ierr);
00134
00135
00136 NumEntries = 0;
00137
00138 for (int j = 0 ; j < Nnz ; ++j) {
00139
00140 if (Indices_[j] < NumRows_ ) {
00141 Indices[NumEntries] = Indices_[j];
00142 Values[NumEntries] = Values_[j];
00143 ++NumEntries;
00144 }
00145 }
00146
00147 return(0);
00148
00149 }
00150
00151
00152 int Ifpack_LocalFilter::ExtractDiagonalCopy(Epetra_Vector & Diagonal) const
00153 {
00154 if (!Diagonal.Map().SameAs(*Map_))
00155 IFPACK_CHK_ERR(-1);
00156 Diagonal = *Diagonal_;
00157 return(0);
00158 }
00159
00160
00161 int Ifpack_LocalFilter::Apply(const Epetra_MultiVector& X,
00162 Epetra_MultiVector& Y) const
00163 {
00164
00165
00166
00167 Y.PutScalar(0.0);
00168 int NumVectors = Y.NumVectors();
00169
00170 double** X_ptr;
00171 double** Y_ptr;
00172 X.ExtractView(&X_ptr);
00173 Y.ExtractView(&Y_ptr);
00174
00175 for (int i = 0 ; i < NumRows_ ; ++i) {
00176
00177 int Nnz;
00178 int ierr = Matrix_->ExtractMyRowCopy(i,MaxNumEntriesA_,Nnz,&Values_[0],
00179 &Indices_[0]);
00180 IFPACK_CHK_ERR(ierr);
00181
00182 for (int j = 0 ; j < Nnz ; ++j) {
00183 if (Indices_[j] < NumRows_ ) {
00184 for (int k = 0 ; k < NumVectors ; ++k)
00185 Y_ptr[k][i] += Values_[j] * X_ptr[k][Indices_[j]];
00186 }
00187 }
00188 }
00189
00190 return(0);
00191 }
00192
00193
00194 int Ifpack_LocalFilter::ApplyInverse(const Epetra_MultiVector& X,
00195 Epetra_MultiVector& Y) const
00196 {
00197 IFPACK_CHK_ERR(-1);
00198 }
00199
00200
00201 const Epetra_BlockMap& Ifpack_LocalFilter::Map() const
00202 {
00203 return(*Map_);
00204 }