EpetraExt Package Browser (Single Doxygen Collection) Development
EpetraExt_PointToBlockDiagPermute.cpp
Go to the documentation of this file.
00001 #include "EpetraExt_PointToBlockDiagPermute.h"
00002 #include "EpetraExt_BlockDiagMatrix.h"
00003 #include "Epetra_MultiVector.h"
00004 #include "Epetra_Import.h"
00005 #include "Epetra_Export.h"
00006 #include "Epetra_Comm.h"
00007 
00008 #include <stdio.h>
00009 #include <fstream>
00010 
00011 #define MAX(x,y) ((x)>(y)?(x):(y))
00012 
00013 //=========================================================================
00014 EpetraExt_PointToBlockDiagPermute::EpetraExt_PointToBlockDiagPermute(const Epetra_CrsMatrix& MAT)
00015   :Epetra_DistObject(MAT.RowMap()),
00016    Matrix_(&MAT),
00017    PurelyLocalMode_(true),
00018    ContiguousBlockMode_(false),
00019    ContiguousBlockSize_(0),
00020    NumBlocks_(0),
00021    Blockstart_(0),
00022    Blockids_(0),
00023    BDMap_(0),
00024    CompatibleMap_(0),
00025    BDMat_(0),
00026    Importer_(0),
00027    Exporter_(0),
00028    ImportVector_(0),
00029    ExportVector_(0)
00030 {
00031 
00032 }
00033   
00034 //=========================================================================  
00035 // Destructor
00036 EpetraExt_PointToBlockDiagPermute::~EpetraExt_PointToBlockDiagPermute()
00037 {
00038   if(BDMap_) delete BDMap_;
00039   if(CompatibleMap_) delete CompatibleMap_;
00040   if(BDMat_) delete BDMat_;
00041   if(Importer_) delete Importer_;
00042   if(Exporter_) delete Exporter_;
00043   if(ImportVector_) delete ImportVector_;
00044   if(ExportVector_) delete ExportVector_;
00045 }
00046 
00047 
00048 
00049 //=========================================================================  
00050 // Set list
00051 int EpetraExt_PointToBlockDiagPermute::SetParameters(Teuchos::ParameterList & List){
00052   List_=List;
00053 
00054   // Check for contiguous blocking first
00055   ContiguousBlockSize_=List_.get("contiguous block size",0);
00056   if(ContiguousBlockSize_!=0){
00057     ContiguousBlockMode_=true;
00058     PurelyLocalMode_=false;
00059   }  
00060   
00061   // Local vs. global ids & mode
00062   NumBlocks_=List_.get("number of local blocks",0);  
00063   Blockstart_=List_.get("block start index",(int*)0);    
00064   Blockids_=List_.get("block entry lids",(int*)0);
00065   if(Blockids_)
00066     PurelyLocalMode_=true;
00067   else{
00068     Blockids_=List_.get("block entry gids",(int*)0);
00069     PurelyLocalMode_=false;
00070   }
00071   
00072   // Sanity checks
00073   if(ContiguousBlockMode_){
00074     // Can't use contiguous at the same time as the other modes
00075     if(NumBlocks_ || Blockstart_ || Blockids_) EPETRA_CHK_ERR(-4);
00076   }
00077   else {
00078     if(NumBlocks_ <= 0) EPETRA_CHK_ERR(-1);
00079     if(!Blockstart_) EPETRA_CHK_ERR(-2);
00080     if(!Blockids_) EPETRA_CHK_ERR(-3);
00081   }
00082   
00083   return 0;
00084 }
00085 
00086 
00087 //=========================================================================  
00088 // Extracts the block-diagonal, builds maps, etc.
00089 int EpetraExt_PointToBlockDiagPermute::Compute(){
00090   int rv=ExtractBlockDiagonal();
00091   return rv;
00092 }
00093 
00094 //=========================================================================  
00095 // Returns the result of a Epetra_Operator applied to a Epetra_MultiVector X in Y.
00096 int EpetraExt_PointToBlockDiagPermute::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00097   return -1;
00098 
00099 }
00100 
00101 //=========================================================================  
00102 // Returns the result of a Epetra_Operator inverse applied to an Epetra_MultiVector X in Y.
00103 int EpetraExt_PointToBlockDiagPermute::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const{
00104   // Stuff borrowed from Epetra_CrsMatrix
00105   int NumVectors = X.NumVectors();
00106   if (NumVectors!=Y.NumVectors()) {
00107     EPETRA_CHK_ERR(-2); // Need same number of vectors in each MV
00108   }
00109 
00110   const Epetra_MultiVector *Xp=&X;
00111   Epetra_MultiVector *Yp=&Y;
00112 
00113   // Allocate temp workspace if X==Y and there are no imports or exports
00114   Epetra_MultiVector * Xcopy = 0;
00115   if (&X==&Y && Importer_==0 && Exporter_==0) {
00116     Xcopy = new Epetra_MultiVector(X);
00117     Xp=Xcopy;
00118   }
00119   
00120   UpdateImportVector(NumVectors); // Make sure Import and Export Vectors are compatible
00121   UpdateExportVector(NumVectors);
00122 
00123   // If we have a non-trivial importer, we must import elements that are permuted or are on other processors
00124   if (Importer_){
00125     EPETRA_CHK_ERR(ImportVector_->Import(X, *Importer_, Insert));
00126     Xp=ImportVector_;
00127   }
00128   
00129   // If we have a non-trivial exporter, we must export elements that are permuted or belong to other processors
00130   if (Exporter_) {
00131     Yp=ExportVector_;
00132   }
00133   
00134   // Do the matvec 
00135   BDMat_->ApplyInverse(*Xp,*Yp);
00136 
00137   // Export if needed
00138   if (Exporter_) {
00139     Y.PutScalar(0.0);  // Make sure target is zero
00140     Y.Export(*ExportVector_, *Exporter_, Add); // Fill Y with Values from export vector
00141   }
00142   
00143   // Cleanup
00144   if(Xcopy) {
00145     delete Xcopy;
00146     EPETRA_CHK_ERR(1); // Return positive code to alert the user about needing extra copy of X
00147     return 1;
00148   }
00149 
00150   return 0;
00151 }
00152 
00153 //=========================================================================  
00154 // Print method
00155 void EpetraExt_PointToBlockDiagPermute::Print(ostream& os) const{
00156   if(Importer_) cout<<*Importer_<<endl;
00157   if(Exporter_) cout<<*Exporter_<<endl;
00158   if(BDMat_) cout<<*BDMat_<<endl;
00159 }
00160 
00161 //=========================================================================  
00162 // Pulls the block diagonal of the matrix and then builds the BDMat_
00163 int EpetraExt_PointToBlockDiagPermute::ExtractBlockDiagonal(){  
00164   int i,j;
00165   std::vector<int> ExtRows;
00166   int* LocalColIDS=0;
00167   int ExtSize=0,ExtCols=0,MainCols=0;
00168   int Nrows=Matrix_->NumMyRows();
00169   int *l2b,*block_offset,*l2blockid;
00170   const Epetra_Map &RowMap=Matrix_->RowMap();
00171   int index,col,row_in_block,col_in_block,length,*colind;
00172   double *values;
00173 
00174   bool verbose=(bool)(List_.get("output",0) > 0);
00175   
00176   // Contiguous Setup
00177   SetupContiguousMode();
00178 
00179   // Compute block size lists
00180   int *bsize=new int[NumBlocks_]; 
00181   for(i=0;i<NumBlocks_;i++) 
00182     bsize[i]=Blockstart_[i+1]-Blockstart_[i];
00183   
00184   // Use the ScanSum function to compute a prefix sum of the number of points
00185   int MyMinGID;
00186   Matrix_->Comm().ScanSum(&NumBlocks_,&MyMinGID, 1);
00187   MyMinGID-=NumBlocks_;
00188   int *MyBlockGIDs=new int[NumBlocks_];
00189   for(i=0;i<NumBlocks_;i++)
00190     MyBlockGIDs[i]=MyMinGID+i;
00191 
00192   BDMap_=new Epetra_BlockMap(-1,NumBlocks_,MyBlockGIDs,bsize,0,Matrix_->Comm());
00193   
00194   // Allocate the Epetra_DistBlockMatrix
00195   BDMat_=new EpetraExt_BlockDiagMatrix(*BDMap_,true);  
00196   
00197   // First check to see if we can switch back to PurelyLocalMode_ if we're not
00198   // in it
00199   if(!PurelyLocalMode_){
00200     // Find the non-local row IDs
00201     ExtSize=MAX(0,Blockstart_[NumBlocks_]-RowMap.NumMyElements());// estimate
00202     ExtRows.reserve(ExtSize);
00203     
00204     for(i=0;i<Blockstart_[NumBlocks_];i++){
00205       if(RowMap.LID(Blockids_[i])==-1)
00206         ExtRows.push_back(Blockids_[i]);
00207     }
00208 
00209     // Switch to PurelyLocalMode_ if we never need GIDs
00210     int size_sum;
00211     ExtSize=ExtRows.size();   
00212     RowMap.Comm().SumAll(&ExtSize,&size_sum,1);
00213     if(size_sum==0){
00214       if(verbose && !Matrix_->Comm().MyPID()) printf("EpetraExt_PointToBlockDiagPermute: Switching to purely local mode\n");
00215       PurelyLocalMode_=true;
00216       for(i=0;i<Blockstart_[NumBlocks_];i++){
00217         Blockids_[i]=RowMap.LID(Blockids_[i]);
00218       }     
00219     }
00220   }
00221   
00222   if(PurelyLocalMode_){
00223     /*******************************************************/
00224     // Allocations
00225     l2b=new int[Nrows];
00226     block_offset=new int[Nrows];
00227 
00228     // Build the local-id-to-block-id list, block offset list    
00229     for(i=0;i<NumBlocks_;i++) {
00230       for(j=Blockstart_[i];j<Blockstart_[i+1];j++){
00231         block_offset[Blockids_[j]]=j-Blockstart_[i];
00232         l2b[Blockids_[j]]=i;
00233       }
00234     }
00235     
00236     // Copy the data to the EpetraExt_BlockDiagMatrix        
00237     for(i=0;i<Nrows;i++) {
00238       int block_num = l2b[i];
00239       if(block_num>=0 && block_num<NumBlocks_) {
00240         row_in_block=block_offset[i];
00241         Matrix_->ExtractMyRowView(i,length,values,colind);
00242         int Nnz=0;
00243         for (j = 0; j < length; j++) {
00244           col = colind[j];
00245           if(col < Nrows && l2b[col]==block_num){
00246             Nnz++;
00247             col_in_block = block_offset[col];
00248             index = col_in_block * bsize[block_num] + row_in_block;
00249             (*BDMat_)[block_num][index]=values[j];
00250           }
00251         }
00252         /* Handle the case of a zero row. */
00253         /* By just putting a 1 on the diagonal. */
00254         if (Nnz == 0) {
00255           index = row_in_block * bsize[block_num] + row_in_block;
00256           (*BDMat_)[block_num][index]=1.0;
00257         }
00258       }
00259     }
00260 
00261     // Build the compatible map for import/export
00262     l2blockid=new int[Nrows];
00263     for(i=0;i<Nrows;i++) 
00264       l2blockid[Blockstart_[l2b[i]]+block_offset[i]]=Matrix_->RowMap().GID(i);
00265 
00266     // Build the Compatible Map, Import/Export Objects
00267     CompatibleMap_=new Epetra_Map(-1,Nrows,l2blockid,0,Matrix_->Comm());
00268     
00269   }
00270   else{
00271     /*******************************************************/      
00272     // Do the import to grab matrix entries
00273     // Allocate temporaries for import
00274     Epetra_Map TmpMap(-1,ExtSize, &ExtRows[0],0,Matrix_->Comm());; 
00275     Epetra_CrsMatrix TmpMatrix(Copy,TmpMap,0);
00276     Epetra_Import TmpImporter(TmpMap,RowMap);
00277 
00278     TmpMatrix.Import(*Matrix_,TmpImporter,Insert);
00279     TmpMatrix.FillComplete();
00280       
00281     ExtCols=TmpMatrix.NumMyCols();
00282     MainCols=Matrix_->NumMyCols();
00283         
00284 
00285     // Build the column reidex - main matrix
00286     LocalColIDS=new int[MainCols+ExtCols];      
00287     for(i=0;i<MainCols;i++){
00288       int GID=Matrix_->GCID(i);
00289       int MainLID=RowMap.LID(GID);
00290       if(MainLID!=-1) LocalColIDS[i]=MainLID;
00291       else{
00292         int ExtLID=TmpMatrix.LRID(GID);
00293         if(ExtLID!=-1) LocalColIDS[i]=Nrows+ExtLID;
00294         else LocalColIDS[i]=-1;
00295       }
00296     }
00297 
00298     // Build the column reidex - ext matrix
00299     for(i=0;i<ExtCols;i++){
00300       int GID=TmpMatrix.GCID(i);
00301       int MainLID=RowMap.LID(GID);
00302       if(MainLID!=-1) LocalColIDS[MainCols+i]=MainLID;
00303       else{
00304         int ExtLID=TmpMatrix.LRID(GID);          
00305         if(ExtLID!=-1) LocalColIDS[MainCols+i]=Nrows+ExtLID;
00306         else LocalColIDS[MainCols+i]=-1;
00307       }
00308     }
00309 
00310     // Allocations
00311     l2b=new int[Nrows+ExtSize];
00312     block_offset=new int[Nrows+ExtSize];  
00313   
00314     // Build l2b/block_offset with the expanded local index
00315     //NTS: Uses the same ordering of operation as the above routine, which is why
00316     //it works.
00317     for(i=0;i<Nrows+ExtSize;i++) block_offset[i]=l2b[i]=-1;    
00318     int ext_idx=0;
00319     for(i=0;i<NumBlocks_;i++) {
00320       for(j=Blockstart_[i];j<Blockstart_[i+1];j++){
00321         int LID=RowMap.LID(Blockids_[j]);
00322         if(LID==-1) {LID=Nrows+ext_idx;ext_idx++;}
00323         block_offset[LID]=j-Blockstart_[i];
00324         l2b[LID]=i;          
00325       }
00326     }
00327     
00328     // Copy the data to the EpetraExt_BlockDiagMatrix from Matrix_
00329     for(i=0;i<Nrows;i++) {
00330       int block_num = l2b[i];
00331       if(block_num>=0 && block_num<NumBlocks_) {
00332         row_in_block=block_offset[i];
00333         Matrix_->ExtractMyRowView(i,length,values,colind);
00334         int Nnz=0;
00335         for (j = 0; j < length; j++) {
00336           col = LocalColIDS[colind[j]];
00337           if(col!=-1 && l2b[col]==block_num){
00338             Nnz++;
00339             col_in_block = block_offset[col];
00340             index = col_in_block * bsize[block_num] + row_in_block;
00341             (*BDMat_)[block_num][index]=values[j];
00342           }
00343         }
00344         /* Handle the case of a zero row. */
00345         /* By just putting a 1 on the diagonal. */
00346         if (Nnz == 0) {
00347           index = row_in_block * bsize[block_num] + row_in_block;
00348           (*BDMat_)[block_num][index]=values[j];
00349         }
00350       }
00351     }
00352     
00353     // Copy the data to the EpetraExt_BlockDiagMatrix from TmpMatrix
00354     for(i=0;i<ExtSize;i++) {
00355       int block_num = l2b[Nrows+i];
00356       if(block_num>=0 && block_num<NumBlocks_) {
00357         row_in_block=block_offset[Nrows+i];
00358         TmpMatrix.ExtractMyRowView(i,length,values,colind);
00359         int Nnz=0;
00360         for (j = 0; j < length; j++) {
00361           col = LocalColIDS[MainCols+colind[j]];
00362           if(col!=-1 && l2b[col]==block_num){
00363             Nnz++;
00364             col_in_block = block_offset[col];
00365             index = col_in_block * bsize[block_num] + row_in_block;
00366             (*BDMat_)[block_num][index]=values[j];
00367           }
00368         }
00369         /* Handle the case of a zero row. */
00370         /* By just putting a 1 on the diagonal. */
00371         if (Nnz == 0) {
00372           index = row_in_block * bsize[block_num] + row_in_block;
00373           (*BDMat_)[block_num][index]=1.0;
00374         }
00375       }      
00376     }
00377     
00378     // Build the compatible map for import/export
00379     l2blockid=new int[Blockstart_[NumBlocks_]];
00380     for(i=0;i<Nrows;i++){
00381       int bkid=l2b[i];
00382       if(bkid>-1) l2blockid[Blockstart_[bkid]+block_offset[i]]=RowMap.GID(i);
00383     }
00384     // NTS: This is easier - if we imported it, we know we need it
00385     for(i=0;i<ExtSize;i++)
00386       l2blockid[Blockstart_[l2b[Nrows+i]]+block_offset[Nrows+i]]=TmpMatrix.GRID(i);
00387     
00388     // Build the Compatible Map, Import/Export Objects
00389     CompatibleMap_=new Epetra_Map(-1,Blockstart_[NumBlocks_],l2blockid,0,Matrix_->Comm());
00390         
00391   }//end else
00392 
00393   // Set BDMat_'s parameter list and compute!
00394   Teuchos::ParameterList dummy,inList;
00395   inList=List_.get("blockdiagmatrix: list",dummy);
00396   BDMat_->SetParameters(inList);  
00397   BDMat_->Compute();
00398   
00399   // Build importer/exporter
00400   if(!CompatibleMap_->SameAs(Matrix_->DomainMap()))
00401     Importer_ = new Epetra_Import(*CompatibleMap_,Matrix_->DomainMap());
00402   if(!CompatibleMap_->SameAs(Matrix_->RangeMap()))
00403     Exporter_ = new Epetra_Export(*CompatibleMap_,Matrix_->RangeMap());
00404 
00405   // Cleanup
00406   delete [] LocalColIDS;
00407   delete [] block_offset;
00408   delete [] l2b;
00409   delete [] l2blockid;
00410   delete [] bsize;
00411   delete [] MyBlockGIDs;
00412 
00413   // Contiguous Cleanup
00414   CleanupContiguousMode();
00415 
00416   return 0;
00417 }
00418 //=======================================================================================================
00419 int EpetraExt_PointToBlockDiagPermute::SetupContiguousMode(){
00420   if(!ContiguousBlockMode_) return 0;
00421   // NTS: In case of processor-crossing blocks, the lowest PID always gets the block;
00422   const Epetra_Map &RowMap=Matrix_->RowMap();
00423   
00424   int MinMyGID=RowMap.MinMyGID(); 
00425   int MaxMyGID=RowMap.MaxMyGID(); 
00426   int Base=Matrix_->IndexBase();
00427 
00428   // Find the GID that begins my first block
00429   int MyFirstBlockGID=ContiguousBlockSize_*(int)ceil(((double)(MinMyGID - Base))/ContiguousBlockSize_)+Base;
00430   NumBlocks_=(int)ceil((double)((MaxMyGID-MyFirstBlockGID+1.0)) / ContiguousBlockSize_);
00431 
00432   // Allocate memory
00433   Blockstart_=new int[NumBlocks_+1];
00434   Blockids_=new int[NumBlocks_*ContiguousBlockSize_];
00435   Blockstart_[NumBlocks_]=NumBlocks_*ContiguousBlockSize_;
00436 
00437   // Fill the arrays
00438   for(int i=0,ct=0;i<NumBlocks_;i++){
00439     Blockstart_[i]=ct;
00440     for(int j=0;j<ContiguousBlockSize_;j++,ct++){
00441       Blockids_[ct]=MyFirstBlockGID+ct;
00442     }
00443   }
00444   
00445   return 0;
00446 }
00447 //=======================================================================================================
00448 int EpetraExt_PointToBlockDiagPermute::CleanupContiguousMode(){
00449   if(!ContiguousBlockMode_) return 0;
00450   NumBlocks_=0;
00451   if(Blockstart_) {delete [] Blockstart_; Blockstart_=0;}
00452   if(Blockids_)   {delete [] Blockids_; Blockids_=0;}
00453   return 0;
00454 }
00455 
00456 
00457 //=======================================================================================================
00458 // Creates an Epetra_CrsMatrix from the BlockDiagMatrix.  This is generally only useful if you want to do a matrix-matrix multiply.
00459 Epetra_FECrsMatrix * EpetraExt_PointToBlockDiagPermute::CreateFECrsMatrix(){
00460   Epetra_FECrsMatrix * NewMat=new Epetra_FECrsMatrix(Copy,Matrix_->RowMap(),0);
00461   
00462   const Epetra_BlockMap &BlockMap=BDMat_->BlockMap();
00463   const Epetra_BlockMap &DataMap=BDMat_->DataMap();
00464   const int *vlist=DataMap.FirstPointInElementList();
00465   const int *xlist=BlockMap.FirstPointInElementList();
00466   const int *blocksize=BlockMap.ElementSizeList();
00467   const double *values=BDMat_->Values();
00468   int NumBlocks=BDMat_->NumMyBlocks();
00469 
00470   // Maximum size vector for stashing GIDs
00471   std::vector<int> GIDs;
00472   GIDs.resize(BlockMap.MaxMyElementSize());
00473 
00474 
00475   for(int i=0;i<NumBlocks;i++){
00476     int Nb=blocksize[i];
00477     int vidx0=vlist[i];
00478     int xidx0=xlist[i];
00479     // Get global indices
00480     for(int j=0;j<Nb;j++)
00481       GIDs[j]=CompatibleMap_->GID(xidx0+j);
00482     
00483     // Remember: We're using column-major storage for LAPACK's benefit    
00484     int ierr=NewMat->InsertGlobalValues(Nb,&GIDs[0],&values[vidx0],Epetra_FECrsMatrix::COLUMN_MAJOR);
00485     if(ierr < 0) throw "CreateFECrsMatrix: ERROR in InsertGlobalValues";
00486   }   
00487   NewMat->GlobalAssemble();
00488   return NewMat;
00489 }
00490 
00491 
00492 //=======================================================================================================
00493 void EpetraExt_PointToBlockDiagPermute::UpdateImportVector(int NumVectors) const {    
00494   if(Importer_ != 0) {
00495     if(ImportVector_ != 0) {
00496       if(ImportVector_->NumVectors() != NumVectors) { 
00497   delete ImportVector_; 
00498   ImportVector_= 0;
00499       }
00500     }
00501     if(ImportVector_ == 0) 
00502       ImportVector_ = new Epetra_MultiVector(*CompatibleMap_,NumVectors); // Create import vector if needed
00503   }
00504   return;
00505 }
00506 //=======================================================================================================
00507 void EpetraExt_PointToBlockDiagPermute::UpdateExportVector(int NumVectors) const {    
00508   if(Exporter_ != 0) {
00509     if(ExportVector_ != 0) {
00510       if(ExportVector_->NumVectors() != NumVectors) { 
00511   delete ExportVector_; 
00512   ExportVector_= 0;
00513       }
00514     }
00515     if(ExportVector_ == 0) 
00516       ExportVector_ = new Epetra_MultiVector(*CompatibleMap_,NumVectors); // Create Export vector if needed
00517   }
00518   return;
00519 }
00520 
00521 
00522 
00523 
00524 //=========================================================================  
00525 int EpetraExt_PointToBlockDiagPermute::Import(const Epetra_SrcDistObject& A, const Epetra_Import& Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor){
00526  return -1;
00527 }
00528 
00529 //=========================================================================  
00530 int EpetraExt_PointToBlockDiagPermute::Import(const Epetra_SrcDistObject& A, const Epetra_Export& Exporter, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor){
00531  return -1;
00532 }
00533 
00534 //=========================================================================  
00535 int EpetraExt_PointToBlockDiagPermute::Export(const Epetra_SrcDistObject& A, const Epetra_Import & Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor){
00536  return -1;
00537 }
00538 
00539 //=========================================================================  
00540 int EpetraExt_PointToBlockDiagPermute::Export(const Epetra_SrcDistObject& A, const Epetra_Export& Exporter, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor){
00541  return -1;
00542 }
00543 
00544 //=========================================================================  
00545 // Allows the source and target (\e this) objects to be compared for compatibility, return nonzero if not.
00546 int EpetraExt_PointToBlockDiagPermute::CheckSizes(const Epetra_SrcDistObject& Source){
00547   return -1;
00548 }
00549 
00550 //=========================================================================  
00551 // Perform ID copies and permutations that are on processor.
00552 int EpetraExt_PointToBlockDiagPermute::CopyAndPermute(const Epetra_SrcDistObject& Source,
00553                    int NumSameIDs, 
00554                    int NumPermuteIDs,
00555                    int * PermuteToLIDs,
00556                    int * PermuteFromLIDs,
00557                    const Epetra_OffsetIndex * Indexor){
00558   return -1;
00559 }
00560 
00561 //=========================================================================  
00562 // Perform any packing or preparation required for call to DoTransfer().
00563 int EpetraExt_PointToBlockDiagPermute::PackAndPrepare(const Epetra_SrcDistObject& Source,
00564                    int NumExportIDs,
00565                    int* ExportLIDs,
00566                    int& LenExports,
00567                    char*& Exports,
00568                    int& SizeOfPacket,
00569                    int* Sizes,
00570                    bool & VarSizes,
00571                    Epetra_Distributor& Distor){
00572   return -1;
00573 }
00574 
00575 //=========================================================================  
00576 // Perform any unpacking and combining after call to DoTransfer().
00577 int EpetraExt_PointToBlockDiagPermute::UnpackAndCombine(const Epetra_SrcDistObject& Source, 
00578                      int NumImportIDs,
00579                      int* ImportLIDs, 
00580                      int LenImports,
00581                      char* Imports,
00582                      int& SizeOfPacket, 
00583                      Epetra_Distributor& Distor,
00584                      Epetra_CombineMode CombineMode,
00585                      const Epetra_OffsetIndex * Indexor){
00586   return -1;
00587 }
00588 
00589 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines