|
EpetraExt Development
|
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
1.7.4