#include "Ifpack_ConfigDefs.h"
#if defined(HAVE_IFPACK_AZTECOO) && defined(HAVE_IFPACK_TEUCHOS) && defined(HAVE_IFPACK_TRIUTILS)
#ifdef HAVE_MPI
#include "Epetra_MpiComm.h"
#else
#include "Epetra_SerialComm.h"
#endif
#include "Epetra_CrsMatrix.h"
#include "Epetra_MultiVector.h"
#include "Epetra_LinearProblem.h"
#include "Epetra_Import.h"
#include "Epetra_Map.h"
#include "Teuchos_ParameterList.hpp"
#include "Teuchos_CommandLineProcessor.hpp"
#include "AztecOO.h"
#include "Ifpack.h"
#include "Ifpack_Utils.h"
int main(int argc, char *argv[])
{
#ifdef HAVE_MPI
MPI_Init(&argc,&argv);
Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
Epetra_SerialComm Comm;
#endif
Teuchos::CommandLineProcessor CLP;
int Overlap = 0;
CLP.setOption("overlap", &Overlap, "Overlap among processes");
int BlockOverlap = 0;
CLP.setOption("block-overlap", &BlockOverlap, "Overlap among blocks");
string PrecType = "ILUT";
CLP.setOption("prec", &PrecType, "IFPACK preconditioner");
int LevelOfFill = 0;
CLP.setOption("fill", &LevelOfFill, "level-of-fill for IC and ILU");
double Relax = 0.0;
CLP.setOption("relax", &Relax, "relaxation value for ICT and ILUT");
double AddToDiag = 1e-5;
CLP.setOption("add-diag", &AddToDiag, "value to be added to diagonals");
double DropTol = 0.0;
CLP.setOption("drop", &DropTol, "drop all elements below this value");
int LocalParts = 4;
CLP.setOption("local-parts", &LocalParts, "number of local blocks");
string FileName = "not-set";
CLP.setOption("matrix", &FileName, "Name of file containing the MTX matrix");
int SymFormat = false;
CLP.setOption("sym-matrix", &SymFormat, "Set to non-zero value if the matrix is stored in symmetric format (that is, only the nonzeros of the lower or upper part are stored)");
CLP.throwExceptions(false);
CLP.parse(argc,argv);
if (FileName == "not-set") {
cerr << "You must at least specify the name of the file" << endl;
cerr << "containing the matrix, using --matrix=my_file.mtx" << endl;
cerr << "Run this example with option --help for more details" << endl;
#ifdef HAVE_MPI
MPI_Finalize();
#endif
exit(EXIT_SUCCESS);
}
int NumRows;
int NumCols;
int Offset = 1;
int NumElements;
std::ifstream data_file;
if (Comm.MyPID() == 0) {
string Title;
data_file.open(FileName.c_str());
if (!data_file.good()) {
cerr << "Error opening file `" << FileName << "'" << endl;
exit(EXIT_FAILURE);
}
char title[100];
data_file.getline(title,100);
data_file >> NumRows;
data_file >> NumCols;
data_file >> NumElements;
assert (NumCols == NumRows);
cout << "Label = `" << title << "'" << endl;
cout << "Number of rows = " << NumRows << endl;
cout << "Number of nonzero elements = " << NumElements << endl;
cout << "Offset = " << Offset << endl;
}
else
NumRows = 0;
Epetra_Map* SerialMap = new Epetra_Map(-1,NumRows,0,Comm);
Epetra_CrsMatrix* SerialMatrix;
SerialMatrix = new Epetra_CrsMatrix(Copy,*SerialMap,0);
if (Comm.MyPID() == 0) {
for (int i = 0 ; i < NumElements ; ++i) {
int row;
int col;
double val;
data_file >> row;
data_file >> col;
data_file >> val;
row -= Offset;
col -= Offset;
IFPACK_CHK_ERR(SerialMatrix->InsertGlobalValues(row,1,&val,&col));
if (col != row && SymFormat)
IFPACK_CHK_ERR(SerialMatrix->InsertGlobalValues(col,1,&val,&row));
}
for (int i = 0 ; i < NumRows ; ++i) {
double val = 0.0;
SerialMatrix->InsertGlobalValues(i,1,&val,&i);
}
}
SerialMatrix->FillComplete();
Comm.Broadcast(&NumRows,1,0);
Epetra_Map DistributedMap(NumRows, 0, Comm);
Epetra_CrsMatrix A(Copy, DistributedMap,0);
Epetra_Import Importer(DistributedMap,*SerialMap);
IFPACK_CHK_ERR(A.Import(*SerialMatrix,
Importer, Insert));
IFPACK_CHK_ERR(A.FillComplete());
delete SerialMap;
delete SerialMatrix;
Teuchos::ParameterList List;
Ifpack Factory;
Ifpack_Preconditioner* Prec = Factory.Create(PrecType, &A, Overlap);
assert(Prec != 0);
List.set("fact: level-of-fill", LevelOfFill);
List.set("fact: relax value", Relax);
List.set("partitioner: overlap", BlockOverlap);
#ifdef HAVE_IFPACK_METIS
List.set("partitioner: type", "METIS");
#else
List.set("partitioner: type", "greedy");
#endif
List.set("partitioner: local parts", LocalParts);
IFPACK_CHK_ERR(Prec->SetParameters(List));
IFPACK_CHK_ERR(Prec->Initialize());
IFPACK_CHK_ERR(Prec->Compute());
double Estimated = Prec->Condest();
if (Comm.MyPID() == 0)
cout << "Estimated condition number = " << Estimated << endl;
Epetra_Vector LHS(A.OperatorDomainMap());
Epetra_Vector RHS(A.OperatorDomainMap());
LHS.PutScalar(1.0);
A.Apply(LHS,RHS);
RHS.Random();
Epetra_LinearProblem Problem(&A,&LHS,&RHS);
AztecOO Solver(Problem);
Solver.SetAztecOption(AZ_solver,AZ_gmres);
Solver.SetAztecOption(AZ_output,32);
Solver.SetPrecOperator(Prec);
Solver.Iterate(1550,1e-5);
delete Prec;
#ifdef HAVE_MPI
MPI_Finalize() ;
#endif
return(EXIT_SUCCESS);
}
#else
#ifdef HAVE_MPI
#include "Epetra_MpiComm.h"
#else
#include "Epetra_SerialComm.h"
#endif
int main(int argc, char *argv[])
{
#ifdef HAVE_MPI
MPI_Init(&argc,&argv);
Epetra_MpiComm Comm( MPI_COMM_WORLD );
#else
Epetra_SerialComm Comm;
#endif
puts("please configure IFPACK with --enable-aztecoo");
puts("--enable-triutils --enable-teuchos");
puts("to run this test");
#ifdef HAVE_MPI
MPI_Finalize() ;
#endif
return(EXIT_SUCCESS);
}
#endif