//============================================================================ Epetra_CrsGraph* Ifpack_CreateOverlappingCrsMatrix(const Epetra_CrsGraph* Graph, const int OverlappingLevel) { if (OverlappingLevel == 0) return(0); // All done if (Graph->Comm().NumProc() == 1) return(0); // All done Epetra_CrsGraph* OverlappingGraph; Epetra_BlockMap* OverlappingMap; OverlappingGraph = const_cast<Epetra_CrsGraph*>(Graph); OverlappingMap = const_cast<Epetra_BlockMap*>(&(Graph->RowMap())); Epetra_CrsGraph* OldGraph; Epetra_BlockMap* OldMap; const Epetra_BlockMap* DomainMap = &(Graph->DomainMap()); const Epetra_BlockMap* RangeMap = &(Graph->RangeMap()); for (int level = 1; level <= OverlappingLevel ; ++level) { OldGraph = OverlappingGraph; OldMap = OverlappingMap; Epetra_Import* OverlappingImporter; OverlappingImporter = const_cast<Epetra_Import*>(OldGraph->Importer()); OverlappingMap = new Epetra_BlockMap(OverlappingImporter->TargetMap()); if (level < OverlappingLevel) OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, 0); else // On last iteration, we want to filter out all columns except // those that correspond // to rows in the graph. This assures that our matrix is square OverlappingGraph = new Epetra_CrsGraph(Copy, *OverlappingMap, *OverlappingMap, 0); OverlappingGraph->Import(*OldGraph, *OverlappingImporter, Insert); if (level < OverlappingLevel) OverlappingGraph->FillComplete(*DomainMap, *RangeMap); else { // Copy last OverlapImporter because we will use it later OverlappingImporter = new Epetra_Import(*OverlappingMap, *DomainMap); OverlappingGraph->FillComplete(*DomainMap, *RangeMap); } if (level > 1) { delete OldGraph; delete OldMap; } delete OverlappingMap; OverlappingGraph->FillComplete(); } return(OverlappingGraph); }
int Epetra_Util::GetPidGidPairs(const Epetra_Import & Importer,std::vector< std::pair<int,long long> > & gpids, bool use_minus_one_for_local){ // Put the (PID,GID) pair in member of Importer.TargetMap() in gpids. If use_minus_one_for_local==true, put in -1 instead of MyPID. // This only works if we have an MpiDistributor in our Importer. Otheriwise return an error. #ifdef HAVE_MPI Epetra_MpiDistributor *D=dynamic_cast<Epetra_MpiDistributor*>(&Importer.Distributor()); if(!D) EPETRA_CHK_ERR(-2); int i,j,k; int mypid=Importer.TargetMap().Comm().MyPID(); int N=Importer.TargetMap().NumMyElements(); // Get the importer's data const int *RemoteLIDs = Importer.RemoteLIDs(); // Get the distributor's data int NumReceives = D->NumReceives(); const int *ProcsFrom = D->ProcsFrom(); const int *LengthsFrom = D->LengthsFrom(); // Resize the outgoing data structure gpids.resize(N); // Start by claiming that I own all the data if(use_minus_one_for_local) for(i=0;i <N; i++) gpids[i]=std::make_pair(-1,Importer.TargetMap().GID64(i)); else for(i=0;i <N; i++) gpids[i]=std::make_pair(mypid,Importer.TargetMap().GID64(i)); // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the // MpiDistributor so it ought to duplicate that effect. for(i=0,j=0;i<NumReceives;i++){ int pid=ProcsFrom[i]; for(k=0;k<LengthsFrom[i];k++){ if(pid!=mypid) gpids[RemoteLIDs[j]].first=pid; j++; } } return 0; #else EPETRA_CHK_ERR(-10); #endif }
//---------------------------------------------------------------------------- int Epetra_Util::GetPids(const Epetra_Import & Importer, std::vector<int> &pids, bool use_minus_one_for_local){ #ifdef HAVE_MPI Epetra_MpiDistributor *D=dynamic_cast<Epetra_MpiDistributor*>(&Importer.Distributor()); if(!D) EPETRA_CHK_ERR(-2); int i,j,k; int mypid=Importer.TargetMap().Comm().MyPID(); int N=Importer.TargetMap().NumMyElements(); // Get the importer's data const int *RemoteLIDs = Importer.RemoteLIDs(); // Get the distributor's data int NumReceives = D->NumReceives(); const int *ProcsFrom = D->ProcsFrom(); const int *LengthsFrom = D->LengthsFrom(); // Resize the outgoing data structure pids.resize(N); // Start by claiming that I own all the data if(use_minus_one_for_local) for(i=0; i<N; i++) pids[i]=-1; else for(i=0; i<N; i++) pids[i]=mypid; // Now, for each remote ID, record who actually owns it. This loop follows the operation order in the // MpiDistributor so it ought to duplicate that effect. for(i=0,j=0;i<NumReceives;i++){ int pid=ProcsFrom[i]; for(k=0;k<LengthsFrom[i];k++){ if(pid!=mypid) pids[RemoteLIDs[j]]=pid; j++; } } return 0; #else EPETRA_CHK_ERR(-10); #endif }
void EpetraGhostView::import(const Epetra_Import& importer, const Epetra_Vector& srcObject) { /* If my vector does not yet exist, create it using the target map of the * importer */ if (ghostView_.get()==0) { ghostView_ = rcp(new Epetra_Vector(importer.TargetMap())); } /* do the import */ int ierr = ghostView_->Import(srcObject, importer, Insert); if (ierr < 0) { Out::os() << "target map=" << endl; importer.TargetMap().Print(Out::os()); Out::os() << "source map=" << endl; srcObject.Map().Print(Out::os()); } TEUCHOS_TEST_FOR_EXCEPTION(ierr < 0, std::runtime_error, "ierr=" << ierr << " in EpetraGhostView::import()"); }
//============================================================================= int Epetra_DistObject::Export(const Epetra_SrcDistObject& A, const Epetra_Import& Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex * Indexor) { if (!Map_.SameAs(Importer.SourceMap())) EPETRA_CHK_ERR(-2); if (!A.Map().SameAs(Importer.TargetMap())) EPETRA_CHK_ERR(-3); int NumSameIDs = Importer.NumSameIDs(); int NumPermuteIDs = Importer.NumPermuteIDs(); int NumRemoteIDs = Importer.NumExportIDs(); int NumExportIDs = Importer.NumRemoteIDs(); int* ExportLIDs = Importer.RemoteLIDs(); int* RemoteLIDs = Importer.ExportLIDs(); int* PermuteToLIDs = Importer.PermuteFromLIDs(); int* PermuteFromLIDs = Importer.PermuteToLIDs(); EPETRA_CHK_ERR(DoTransfer(A, CombineMode, NumSameIDs, NumPermuteIDs, NumRemoteIDs, NumExportIDs, PermuteToLIDs, PermuteFromLIDs, RemoteLIDs, ExportLIDs, LenImports_, Imports_, LenExports_, Exports_, Importer.Distributor(), true, Indexor)); return(0); }
//============================================================================ Epetra_CrsMatrix* Ifpack_CreateOverlappingCrsMatrix(const Epetra_RowMatrix* Matrix, const int OverlappingLevel) { if (OverlappingLevel == 0) return(0); // All done if (Matrix->Comm().NumProc() == 1) return(0); // All done Epetra_CrsMatrix* OverlappingMatrix; OverlappingMatrix = 0; Epetra_Map* OverlappingMap; OverlappingMap = (Epetra_Map*)&(Matrix->RowMatrixRowMap()); const Epetra_RowMatrix* OldMatrix; const Epetra_Map* DomainMap = &(Matrix->OperatorDomainMap()); const Epetra_Map* RangeMap = &(Matrix->OperatorRangeMap()); for (int level = 1; level <= OverlappingLevel ; ++level) { if (OverlappingMatrix) OldMatrix = OverlappingMatrix; else OldMatrix = Matrix; Epetra_Import* OverlappingImporter; OverlappingImporter = (Epetra_Import*)OldMatrix->RowMatrixImporter(); int NumMyElements = OverlappingImporter->TargetMap().NumMyElements(); // need to build an Epetra_Map in this way because Epetra_CrsMatrix // requires Epetra_Map and not Epetra_BlockMap #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES if(OverlappingImporter->TargetMap().GlobalIndicesInt()) { int* MyGlobalElements = OverlappingImporter->TargetMap().MyGlobalElements(); OverlappingMap = new Epetra_Map(-1,NumMyElements,MyGlobalElements, 0, Matrix->Comm()); } else #endif #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES if(OverlappingImporter->TargetMap().GlobalIndicesLongLong()) { long long* MyGlobalElements = OverlappingImporter->TargetMap().MyGlobalElements64(); OverlappingMap = new Epetra_Map((long long) -1,NumMyElements,MyGlobalElements, 0, Matrix->Comm()); } else #endif throw "Ifpack_CreateOverlappingCrsMatrix: GlobalIndices type unknown"; if (level < OverlappingLevel) OverlappingMatrix = new Epetra_CrsMatrix(Copy, *OverlappingMap, 0); else // On last iteration, we want to filter out all columns except // those that correspond // to rows in the graph. This assures that our matrix is square OverlappingMatrix = new Epetra_CrsMatrix(Copy, *OverlappingMap, *OverlappingMap, 0); OverlappingMatrix->Import(*OldMatrix, *OverlappingImporter, Insert); if (level < OverlappingLevel) { OverlappingMatrix->FillComplete(*DomainMap, *RangeMap); } else { OverlappingMatrix->FillComplete(*DomainMap, *RangeMap); } delete OverlappingMap; if (level > 1) { delete OldMatrix; } OverlappingMatrix->FillComplete(); } return(OverlappingMatrix); }