44 #if defined(HAVE_IFPACK_AZTECOO) && defined(HAVE_IFPACK_EPETRAEXT)
46 #include "Epetra_MpiComm.h"
48 #include "Epetra_SerialComm.h"
50 #include "Epetra_CrsMatrix.h"
51 #include "Epetra_Vector.h"
52 #include "Epetra_LinearProblem.h"
53 #include "Trilinos_Util_CrsMatrixGallery.h"
54 #include "Teuchos_ParameterList.hpp"
60 #include "EpetraExt_BlockDiagMatrix.h"
61 #include "EpetraExt_PointToBlockDiagPermute.h"
64 using namespace Trilinos_Util;
70 static bool Solver = AZ_gmres;
79 const int NUM_BLOCKS=30;
81 long long my_blockgids[NUM_BLOCKS];
82 int my_blocksizes[NUM_BLOCKS];
84 for(
int i=0;i<NUM_BLOCKS;i++){
85 my_blockgids[i]=i+((
long long)NUM_BLOCKS)*Comm.
MyPID();
88 else if(i<2*NUM_BLOCKS/3)
96 Epetra_BlockMap BDMap(-1LL,NUM_BLOCKS,my_blockgids,my_blocksizes,0LL,Comm);
100 for(
int i=0;i<BMAT.NumMyBlocks();i++){
101 double*start=BMAT[i];
102 if(BMAT.BlockSize(i)==1)
104 else if(BMAT.BlockSize(i)==2){
110 else if(BMAT.BlockSize(i)==3){
138 List.
set(
"apply mode",
"invert");
139 BMAT.SetParameters(List);
140 X.SetSeed(24601); X.Random();
141 BMAT_forward.ApplyInverse(X,Y);
143 BMAT.ApplyInverse(Y,Z);
144 X.Update(1.0,Z,-1.0);
146 if(!Comm.
MyPID()) cout<<
"Forward/Invert Error = "<<norm2<<endl;
147 if(norm2 > 1e-12) TestPassed=
false;
152 List.
set(
"apply mode",
"factor");
153 BMAT_factor.SetParameters(List);
154 X.SetSeed(24601); X.Random();
155 BMAT_forward.ApplyInverse(X,Y);
156 BMAT_factor.Compute();
157 BMAT_factor.ApplyInverse(Y,Z);
158 X.Update(1.0,Z,-1.0);
160 if(!Comm.
MyPID()) cout<<
"Forward/Factor Error = "<<norm2<<endl;
161 if(norm2 > 1e-12) TestPassed=
false;
169 void Build_Local_Contiguous_Size2_BlockMatrix(
const Epetra_Comm & Comm,
int NUM_ROWS,
int &NumBlocks,
171 double values[3]={-1.0,2.0,-1.0};
172 long long indices[3];
180 Blockstart_=
new int [NumBlocks+1];
187 int row_in_block=i%2;
189 Blockstart_[curr_block]=i;
190 indices[0]=i; indices[1]=i+1;
194 else if(row_in_block==1){
195 indices[0]=i-1; indices[1]=i;
207 void Build_Local_NonContiguous_Size2_BlockMatrix(
const Epetra_Comm & Comm,
int NUM_ROWS,
int &NumBlocks,
209 double values[3]={-1.0,2.0,-1.0};
210 long long indices[3];
218 Blockstart_=
new int [NumBlocks+1];
224 int row_in_block=(i%2)?1:0;
227 Blockstart_[curr_block]=i;
228 indices[0]=Map.GID64(idx); indices[1]=Map.GID64(idx+NumBlocks);
233 else if(row_in_block==1){
234 int idx=(i-1)/2+NumBlocks;
235 indices[0]=Map.GID64(idx-NumBlocks); indices[1]=Map.GID64(idx);
246 void Build_NonLocal_BlockMatrix(
const Epetra_Comm & Comm,
int NUM_ROWS,
int &NumBlocks,
248 double values[3]={-1.0,2.0,-1.0};
249 long long indices[3];
255 int MyPID=Comm.
MyPID();
258 long long GID=Map.GID64(i);
260 if(i==0) values[1]=2.0;
261 else values[1]=NumProcs+1;
266 if(NumProcs>1 && MyPID==0 && i>0){
268 for(
int j=1;j<NumProcs;j++){
269 indices[1]+=NUM_ROWS;
273 else if(NumProcs>1 && MyPID!=0 && i>0){
274 indices[1]=GID%NUM_ROWS;
283 if(MyPID==0) NumBlocks=NUM_ROWS;
285 Blockstart_=
new int [NumBlocks+1];
287 int curr_idx,curr_block;
291 Blockids_=
new long long[1];
292 Blockstart_[0]=0; Blockstart_[1]=1;
293 Blockids_[0]=Map.GID64(0);
297 int nnz=NumProcs*NumBlocks;
298 Blockids_=
new long long[nnz+1];
300 Blockids_[0]=Map.GID64(0);
301 curr_idx=1; curr_block=1;
302 for(
int j=1;j<NUM_ROWS;j++){
303 Blockstart_[curr_block]=curr_idx;
304 for(
int i=0;i<NumProcs;i++){
305 Blockids_[curr_idx]=((
long long)NUM_ROWS)*i+j;
310 Blockstart_[curr_block]=curr_idx;
315 void Build_DiagonalStructure(
const Epetra_Map &Map,
int &NumBlocks,
int *&Blockstart_,
int *&Blockids_int_,
long long *&Blockids_LL_,
bool local_ids){
318 Blockids_int_=
new int[NumBlocks];
320 Blockids_LL_=
new long long[NumBlocks];
321 Blockstart_=
new int[NumBlocks+1];
322 for(
int i=0;i<NumBlocks;i++){
324 if(local_ids) Blockids_int_[i]=i;
325 else Blockids_LL_[i]=Map.
GID64(i);
327 Blockstart_[NumBlocks]=NumBlocks;
335 double Test_PTBDP(
const Epetra_CrsMatrix& MAT,
int NumBlocks,
int* Blockstart_,
int* Blockids_int_,
long long* Blockids_LL_,
bool is_lid){
338 List.
set(
"number of local blocks",NumBlocks);
339 List.
set(
"block start index",Blockstart_);
340 if(is_lid) List.
set(
"block entry lids",Blockids_int_);
341 else List.
set(
"block entry gids",Blockids_LL_);
343 Sublist.
set(
"apply mode",
"invert");
345 List.
set(
"blockdiagmatrix: list",Sublist);
348 Perm.SetParameters(List);
354 X.SetSeed(24601); X.Random();
357 Perm.ApplyInverse(X,Y);
359 X.Update(1.0,Z,-1.0);
369 List.
set(
"contiguous block size",BlockSize);
371 Sublist.
set(
"apply mode",
"invert");
373 List.
set(
"blockdiagmatrix: list",Sublist);
376 Perm.SetParameters(List);
382 X.SetSeed(24601); X.Random();
385 Perm.ApplyInverse(X,Y);
387 X.Update(1.0,Z,-1.0);
393 bool TestPointToBlockDiagPermute(
const Epetra_Comm & Comm){
397 const int NUM_ROWS=64;
399 bool TestPassed=
true;
401 int NumBlocks, *Blockstart_;
403 long long *Blockids_LL_;
407 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
408 norm2=Test_PTBDP(*MAT,NumBlocks,Blockstart_,Blockids_int_,0,
true);
409 if(norm2 > 1e-12) TestPassed=
false;
410 if(!Comm.
MyPID()) cout<<
"P2BDP LCMAT Error = "<<norm2<<endl;
411 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
414 Build_Local_NonContiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
415 norm2=Test_PTBDP(*MAT,NumBlocks,Blockstart_,Blockids_int_,0,
true);
416 if(norm2 > 1e-12) TestPassed=
false;
417 if(!Comm.
MyPID()) cout<<
"P2BDP LNCMat Error = "<<norm2<<endl;
418 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
421 Build_NonLocal_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_LL_,MAT);
422 norm2=Test_PTBDP(*MAT,NumBlocks,Blockstart_,0,Blockids_LL_,
false);
423 if(norm2 > 1e-12) TestPassed=
false;
424 if(!Comm.
MyPID()) cout<<
"P2BDP NLMat Error = "<<norm2<<endl;
425 delete MAT;
delete [] Blockstart_;
delete [] Blockids_LL_;
428 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
429 norm2=Test_PTBDP_C(*MAT,2);
430 if(norm2 > 1e-12) TestPassed=
false;
431 if(!Comm.
MyPID()) cout<<
"P2BDP LCMAT-C Error = "<<norm2<<endl;
432 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
440 double Test_Cheby(
const Epetra_CrsMatrix& MAT,
int NumBlocks,
int* Blockstart_,
int* Blockids_int_,
long long* Blockids_LL_,
int maxits,
bool is_lid){
444 List.
set(
"number of local blocks",NumBlocks);
445 List.
set(
"block start index",Blockstart_);
446 if(is_lid) List.
set(
"block entry lids",Blockids_int_);
447 else List.
set(
"block entry gids",Blockids_LL_);
449 Sublist.
set(
"apply mode",
"invert");
450 List.
set(
"blockdiagmatrix: list",Sublist);
452 ChebyList.
set(
"chebyshev: use block mode",
true);
453 ChebyList.
set(
"chebyshev: block list",List);
454 ChebyList.
set(
"chebyshev: eigenvalue autocompute ratio",30.0);
455 ChebyList.
set(
"chebyshev: degree",maxits);
459 Cheby.SetParameters(ChebyList);
465 X.SetSeed(24601); X.Random();
469 Cheby.ApplyInverse(Y,Z);
470 X.Update(1.0,Z,-1.0);
472 return norm2 / norm0;
480 List.
set(
"contiguous block size",BlockSize);
481 Sublist.
set(
"apply mode",
"invert");
482 List.
set(
"blockdiagmatrix: list",Sublist);
484 ChebyList.
set(
"chebyshev: use block mode",
true);
485 ChebyList.
set(
"chebyshev: block list",List);
486 ChebyList.
set(
"chebyshev: eigenvalue autocompute ratio",30.0);
487 ChebyList.
set(
"chebyshev: degree",maxits);
491 Cheby.SetParameters(ChebyList);
497 X.SetSeed(24601); X.Random();
501 Cheby.ApplyInverse(Y,Z);
502 X.Update(1.0,Z,-1.0);
504 return norm2 / norm0;
513 const int NUM_ROWS=100;
515 bool TestPassed=
true;
517 int NumBlocks, *Blockstart_;
519 long long *Blockids_LL_;
523 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
524 delete [] Blockstart_;
delete [] Blockids_int_;
525 Build_DiagonalStructure(MAT->
RowMap(),NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,
true);
526 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,100,
true);
527 if(norm2 > 1e-12) TestPassed=
false;
528 if(!Comm.
MyPID()) cout<<
"Cheby LC-D nrm-red = "<<norm2<<endl;
529 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
532 Build_Local_NonContiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
533 delete [] Blockstart_;
delete [] Blockids_int_;
534 Build_DiagonalStructure(MAT->
RowMap(),NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,
true);
535 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,100,
true);
536 if(norm2 > 1e-12) TestPassed=
false;
537 if(!Comm.
MyPID()) cout<<
"Cheby LNC-D nrm-red = "<<norm2<<endl;
538 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
541 Build_NonLocal_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_LL_,MAT);
542 delete [] Blockstart_;
delete [] Blockids_LL_;
543 Build_DiagonalStructure(MAT->
RowMap(),NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,
false);
544 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,100,
false);
545 if(norm2 > 1e-12) TestPassed=
false;
546 if(!Comm.
MyPID()) cout<<
"Cheby NL-D nrm-red = "<<norm2<<endl;
547 delete MAT;
delete [] Blockstart_;
delete [] Blockids_LL_;
550 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
551 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,1,
true);
552 if(norm2 > 1e-12) TestPassed=
false;
553 if(!Comm.
MyPID()) cout<<
"Cheby LC-E nrm-red = "<<norm2<<endl;
554 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
557 Build_Local_NonContiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
558 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,1,
true);
559 if(norm2 > 1e-12) TestPassed=
false;
560 if(!Comm.
MyPID()) cout<<
"Cheby LNC-E nrm-red = "<<norm2<<endl;
561 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
564 Build_NonLocal_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_LL_,MAT);
565 norm2=Test_Cheby(*MAT,NumBlocks,Blockstart_,Blockids_int_,Blockids_LL_,1,
false);
566 if(norm2 > 1e-12) TestPassed=
false;
567 if(!Comm.
MyPID()) cout<<
"Cheby NL-E nrm-red = "<<norm2<<endl;
568 delete MAT;
delete [] Blockstart_;
delete [] Blockids_LL_;
571 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
572 norm2=Test_Cheby_C(*MAT,1,100);
573 if(norm2 > 1e-12) TestPassed=
false;
574 if(!Comm.
MyPID()) cout<<
"Cheby LC-Dc nrm-red = "<<norm2<<endl;
575 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
578 Build_Local_Contiguous_Size2_BlockMatrix(Comm,NUM_ROWS,NumBlocks,Blockstart_,Blockids_int_,MAT);
579 norm2=Test_Cheby_C(*MAT,2,1);
580 if(norm2 > 1e-12) TestPassed=
false;
581 if(!Comm.
MyPID()) cout<<
"Cheby LC-Ec nrm-red = "<<norm2<<endl;
582 delete MAT;
delete [] Blockstart_;
delete [] Blockids_int_;
590 int main(
int argc,
char *argv[])
596 MPI_Init(&argc,&argv);
601 bool TestPassed=
true;
604 TestPassed=TestPassed && TestBlockDiagMatrix(Comm);
607 TestPassed=TestPassed && TestPointToBlockDiagPermute(Comm);
610 TestPassed=TestPassed && TestBlockChebyshev(Comm);
617 if(!Comm.
MyPID()) cout <<
"Test `BlockCheby.exe' FAILED!" << endl;
624 if(!Comm.
MyPID()) cout <<
"Test `BlockCheby.exe' passed!" << endl;
631 #include "Epetra_MpiComm.h"
633 #include "Epetra_SerialComm.h"
636 int main(
int argc,
char *argv[])
640 MPI_Init(&argc,&argv);
646 puts(
"please configure IFPACK with --eanble-aztecoo --enable-teuchos --enable-epetraext");
647 puts(
"to run this test");
652 return(EXIT_SUCCESS);
virtual int InsertGlobalValues(int GlobalRow, int NumEntries, const double *Values, const int *Indices)
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
ParameterList & set(std::string const &name, T &&value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
virtual int MyPID() const =0
int FillComplete(bool OptimizeDataStorage=true)
const Epetra_Map & RowMap() const
int NumMyElements() const
long long GID64(int LID) const
Ifpack_Chebyshev: class for preconditioning with Chebyshev polynomials in Ifpack. ...
int main(int argc, char *argv[])
virtual int NumProc() const =0