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
00031
00032
00033
00034
00035
00036
00037
00038 #include "Ifpack_ConfigDefs.h"
00039
00040 #ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS
00041
00042 #include <vector>
00043 #include <algorithm>
00044
00045 #include "Epetra_MultiVector.h"
00046 #include "Epetra_Vector.h"
00047 #include "Epetra_IntVector.h"
00048 #include "Epetra_RowMatrix.h"
00049 #include "Epetra_Map.h"
00050 #include "Epetra_BlockMap.h"
00051 #include "Ifpack_OverlappingRowMatrix.h"
00052 #include "Epetra_Import.h"
00053 #include "Epetra_Export.h"
00054 #include "Epetra_CrsMatrix.h"
00055 #include "Epetra_BLAS_wrappers.h"
00056
00057 #include "Ifpack_SubdomainFilter.h"
00058
00059 using namespace Teuchos;
00060
00061
00062 Ifpack_SubdomainFilter::Ifpack_SubdomainFilter(const RefCountPtr<const Epetra_RowMatrix>& Matrix,int subdomainId) :
00063 Matrix_(Matrix),
00064 NumMyRows_(0),
00065 NumMyNonzeros_(0),
00066 NumGlobalRows_(0),
00067 NumGlobalCols_(0),
00068 MaxNumEntries_(0),
00069 MaxNumEntriesA_(0)
00070 {
00071 sprintf(Label_,"%s","Ifpack_SubdomainFilter");
00072
00073 ImportVector_ = 0;
00074 ExportVector_ = 0;
00075
00076 ovA_ = dynamic_cast<const Ifpack_OverlappingRowMatrix*>(&*Matrix_);
00077
00078 if (ovA_) {
00079 Acrs_=dynamic_cast<const Epetra_CrsMatrix*>(&ovA_->A());
00080 NumMyRowsA_ = ovA_->A().NumMyRows();
00081 NumMyRowsB_ = ovA_->B().NumMyRows();
00082 } else {
00083 NumMyRowsA_ = Matrix->NumMyRows();
00084 NumMyRowsB_ = 0;
00085 }
00086
00087 #ifdef HAVE_MPI
00088 const Epetra_MpiComm *pComm = dynamic_cast<const Epetra_MpiComm*>( &(Matrix->Comm()) );
00089 assert(pComm != NULL);
00090 MPI_Comm_split(pComm->Comm(), subdomainId, pComm->MyPID(), &subdomainMPIComm_);
00091 SubComm_ = rcp( new Epetra_MpiComm(subdomainMPIComm_) );
00092 #else
00093 SubComm_ = rcp( new Epetra_SerialComm );
00094 #endif
00095
00096 NumMyRows_ = Matrix->NumMyRows();
00097 SubComm_->SumAll(&NumMyRows_,&NumGlobalRows_,1);
00098
00099
00100 const Epetra_Map &globRowMap = Matrix->RowMatrixRowMap();
00101 std::vector<int> myRowsGID(NumMyRows_);
00102 globRowMap.MyGlobalElements(&myRowsGID[0]);
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 int MaxLocalRows = 0;
00116 SubComm_->MaxAll(&NumMyRows_, &MaxLocalRows, 1);
00117
00118 std::vector<int> SubdomainRowGID(SubComm_->NumProc() * MaxLocalRows);
00119 myRowsGID.resize(MaxLocalRows, -1);
00120
00121 SubComm_->GatherAll(&myRowsGID[0],
00122 &SubdomainRowGID[0],
00123 MaxLocalRows);
00124
00125 std::sort(SubdomainRowGID.begin(), SubdomainRowGID.end());
00126
00127 int PaddingSize = SubdomainRowGID.size() - NumGlobalRows_;
00128 SubdomainRowGID.erase(SubdomainRowGID.begin(),
00129 SubdomainRowGID.begin() + PaddingSize);
00130
00131
00132 const Epetra_Map &globColMap = Matrix->RowMatrixColMap();
00133 NumMyCols_ = globColMap.NumMyElements();
00134 std::vector<int> myGlobalCols(NumMyCols_);
00135 globColMap.MyGlobalElements(&myGlobalCols[0]);
00136
00137
00138 std::vector<int> filteredColGID;
00139 for (int i = 0; i < NumMyCols_; ++i) {
00140 if (std::find(SubdomainRowGID.begin(), SubdomainRowGID.end(),
00141 myGlobalCols[i]) != SubdomainRowGID.end()) {
00142 filteredColGID.push_back(myGlobalCols[i]);
00143 }
00144 }
00145 NumMyCols_ = filteredColGID.size();
00146
00147
00148 Map_ = rcp( new Epetra_Map(-1, NumMyRows_, &myRowsGID[0], globRowMap.IndexBase(), *SubComm_) );
00149 colMap_ = rcp( new Epetra_Map(-1, NumMyCols_, &filteredColGID[0], globColMap.IndexBase(), *SubComm_) );
00150 NumGlobalCols_ = NumGlobalRows_;
00151
00152 NumEntries_.resize(NumMyRows_);
00153 MaxNumEntriesA_ = Matrix->MaxNumEntries();
00154 MaxNumEntries_ = Matrix->MaxNumEntries();
00155
00156 Diagonal_ = rcp( new Epetra_Vector(*Map_) );
00157 if (Diagonal_ == Teuchos::null) IFPACK_CHK_ERRV(-5);
00158
00159 Indices_.resize(MaxNumEntries_);
00160 Values_.resize(MaxNumEntries_);
00161
00162 Ac_LIDMap_ = 0;
00163 Bc_LIDMap_ = 0;
00164 Ar_LIDMap_ = 0;
00165 Br_LIDMap_ = 0;
00166
00167 if(ovA_){
00168 Ac_LIDMap_ = new int[ovA_->A().NumMyCols() + 1];
00169 for(int i = 0; i < ovA_->A().NumMyCols(); i++) {
00170 Ac_LIDMap_[i] = colMap_->LID(ovA_->A().RowMatrixColMap().GID(i));
00171 }
00172 Bc_LIDMap_ = new int[ovA_->B().NumMyCols() + 1];
00173 for(int i = 0; i < ovA_->B().NumMyCols(); i++) {
00174 Bc_LIDMap_[i] = colMap_->LID(ovA_->B().RowMatrixColMap().GID(i));
00175 }
00176 Ar_LIDMap_ = new int[ovA_->A().NumMyRows() + 1];
00177 for(int i = 0; i < ovA_->A().NumMyRows(); i++) {
00178 Ar_LIDMap_[i] = Map_->LID(ovA_->A().RowMatrixRowMap().GID(i));
00179 }
00180 Br_LIDMap_ = new int[ovA_->B().NumMyRows() + 1];
00181 for(int i = 0; i < ovA_->B().NumMyRows(); i++) {
00182 Br_LIDMap_[i] = Map_->LID(ovA_->B().RowMatrixRowMap().GID(i));
00183 }
00184 }
00185
00186 int ActualMaxNumEntries = 0;
00187
00188 for (int i = 0 ; i < NumMyRows_; ++i) {
00189 NumEntries_[i] = 0;
00190 int Nnz;
00191 IFPACK_CHK_ERRV(ExtractMyRowCopy(i, MaxNumEntries_, Nnz, &Values_[0], &Indices_[0]));
00192
00193 for (int j = 0 ; j < Nnz; ++j) {
00194 if (Indices_[j] == i) {
00195 (*Diagonal_)[i] = Values_[j];
00196 }
00197 }
00198
00199 if (Nnz > ActualMaxNumEntries) {
00200 ActualMaxNumEntries = Nnz;
00201 }
00202
00203 NumMyNonzeros_ += Nnz;
00204 NumEntries_[i] = Nnz;
00205 }
00206
00207 SubComm_->SumAll(&NumMyNonzeros_, &NumGlobalNonzeros_, 1);
00208 MaxNumEntries_ = ActualMaxNumEntries;
00209
00210 int gpid = Matrix->Comm().MyPID();
00211 Exporter_ = null;
00212 Importer_ = null;
00213
00214 if (!(RowMatrixRowMap().SameAs(OperatorRangeMap()))) {
00215 try{
00216 Exporter_ = rcp(new Epetra_Export(RowMatrixRowMap(), OperatorRangeMap()));
00217 }
00218 catch(...) {
00219 printf("** * gpid %d: Ifpack_SubdomainFilter ctor: problem creating Exporter_ * **\n\n",gpid);
00220 }
00221 }
00222
00223 if (!(*colMap_).SameAs(*Map_)) {
00224 try{
00225 Importer_ = rcp(new Epetra_Import(*colMap_, *Map_));
00226 }
00227 catch(...) {
00228 printf("** * gpid %d: Ifpack_SubdomainFilter ctor: problem creating Importer_ * **\n\n",gpid);
00229 }
00230 }
00231
00232 }
00233
00234
00235 Ifpack_SubdomainFilter::~Ifpack_SubdomainFilter()
00236 {
00237 if(Ac_LIDMap_) delete [] Ac_LIDMap_;
00238 if(Bc_LIDMap_) delete [] Bc_LIDMap_;
00239 if(Ar_LIDMap_) delete [] Ar_LIDMap_;
00240 if(Br_LIDMap_) delete [] Br_LIDMap_;
00241
00242 if(ImportVector_) delete ImportVector_;
00243 }
00244
00245
00246 int Ifpack_SubdomainFilter:: ExtractMyRowCopy(int MyRow, int Length, int & NumEntries,
00247 double *Values, int * Indices) const
00248 {
00249 if ((MyRow < 0) || (MyRow >= NumMyRows_)) {
00250 IFPACK_CHK_ERR(-1);
00251 }
00252
00253 assert(Length >= NumEntries_[MyRow]);
00254
00255 int ierr;
00256 if (ovA_) {
00257 int LocRow = ovA_->A().RowMatrixRowMap().LID(Map_->GID(MyRow));
00258 if (LocRow != -1) {
00259 ierr = ovA_->A().ExtractMyRowCopy(LocRow, Length, NumEntries, Values, Indices);
00260 for(int j = 0;j < NumEntries; j++) {
00261 Indices[j] = Ac_LIDMap_[Indices[j]];
00262 }
00263 }
00264 else {
00265 LocRow = ovA_->B().RowMatrixRowMap().LID(Map_->GID(MyRow));
00266 ierr = ovA_->B().ExtractMyRowCopy(LocRow, Length, NumEntries, Values, Indices);
00267 for(int j = 0; j < NumEntries; j++) {
00268 Indices[j] = Bc_LIDMap_[Indices[j]];
00269 }
00270 }
00271 } else {
00272 int Nnz = 0;
00273 ierr = Matrix_->ExtractMyRowCopy(MyRow, MaxNumEntriesA_, Nnz, &Values_[0], &Indices_[0]);
00274 IFPACK_CHK_ERR(ierr);
00275
00276 NumEntries = 0;
00277 for (int j = 0 ; j < Nnz ; ++j) {
00278 int subdomainLocalIndex = colMap_->LID(Matrix_->RowMatrixColMap().GID(Indices_[j]));
00279 if (subdomainLocalIndex != -1) {
00280 Indices[NumEntries] = subdomainLocalIndex;
00281 Values[NumEntries] = Values_[j];
00282 NumEntries++;
00283 }
00284 }
00285 }
00286
00287 return(ierr);
00288 }
00289
00290
00291 int Ifpack_SubdomainFilter::ExtractDiagonalCopy(Epetra_Vector & Diagonal) const
00292 {
00293 if (!Diagonal.Map().SameAs(*Map_)) {
00294 IFPACK_CHK_ERR(-1);
00295 }
00296
00297 Diagonal = *Diagonal_;
00298 return(0);
00299 }
00300
00301
00302 int Ifpack_SubdomainFilter::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const
00303 {
00304 std::cout << "Ifpack_SubdomainFilter::Apply not implemented.\n";
00305 IFPACK_CHK_ERR(-1);
00306 }
00307
00308
00309 void Ifpack_SubdomainFilter::UpdateImportVector(int NumVectors) const
00310 {
00311 }
00312
00313
00314 void Ifpack_SubdomainFilter::UpdateExportVector(int NumVectors) const
00315 {
00316 }
00317
00318
00319 int Ifpack_SubdomainFilter::ApplyInverse(const Epetra_MultiVector& X,
00320 Epetra_MultiVector& Y) const
00321 {
00322 std::cout << "Ifpack_SubdomainFilter::ApplyInverse not implemented.\n";
00323 IFPACK_CHK_ERR(-1);
00324 }
00325
00326
00327 const Epetra_BlockMap& Ifpack_SubdomainFilter::Map() const
00328 {
00329 return(*Map_);
00330 }
00331
00332 #endif //ifdef HAVE_IFPACK_PARALLEL_SUBDOMAIN_SOLVERS