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