int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm (MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // The problem is defined on a 2D grid, global size is nx * nx. int nx = 30; Teuchos::ParameterList GaleriList; GaleriList.set("nx", nx); GaleriList.set("ny", nx * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Cartesian2D", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); Teuchos::RefCountPtr<Epetra_MultiVector> LHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) ); Teuchos::RefCountPtr<Epetra_MultiVector> RHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) ); LHS->PutScalar(0.0); RHS->Random(); // ========================================= // // Compare IC preconditioners to no precond. // // ----------------------------------------- // const double tol = 1e-5; const int maxIter = 500; // Baseline: No preconditioning // Compute number of iterations, to compare to IC later. // Here we create an AztecOO object LHS->PutScalar(0.0); AztecOO solver; solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_cg); //solver.SetPrecOperator(&*PrecDiag); solver.SetAztecOption(AZ_output, 16); solver.Iterate(maxIter, tol); int Iters = solver.NumIters(); //cout << "No preconditioner iterations: " << Iters << endl; #if 0 // Not sure how to use Ifpack_CrsRick - leave out for now. // // I wanna test funky values to be sure that they have the same // influence on the algorithms, both old and new int LevelFill = 2; double DropTol = 0.3333; double Condest; Teuchos::RefCountPtr<Ifpack_CrsRick> IC; Ifpack_IlukGraph mygraph (A->Graph(), 0, 0); IC = Teuchos::rcp( new Ifpack_CrsRick(*A, mygraph) ); IC->SetAbsoluteThreshold(0.00123); IC->SetRelativeThreshold(0.9876); // Init values from A IC->InitValues(*A); // compute the factors IC->Factor(); // and now estimate the condition number IC->Condest(false,Condest); if( Comm.MyPID() == 0 ) { cout << "Condition number estimate (level-of-fill = " << LevelFill << ") = " << Condest << endl; } // Define label for printing out during the solve phase std::string label = "Ifpack_CrsRick Preconditioner: LevelFill = " + toString(LevelFill) + " Overlap = 0"; IC->SetLabel(label.c_str()); // Here we create an AztecOO object LHS->PutScalar(0.0); AztecOO solver; solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_cg); solver.SetPrecOperator(&*IC); solver.SetAztecOption(AZ_output, 16); solver.Iterate(maxIter, tol); int RickIters = solver.NumIters(); //cout << "Ifpack_Rick iterations: " << RickIters << endl; // Compare to no preconditioning if (RickIters > Iters/2) IFPACK_CHK_ERR(-1); #endif ////////////////////////////////////////////////////// // Same test with Ifpack_IC // This is Crout threshold Cholesky, so different than IC(0) Ifpack Factory; Teuchos::RefCountPtr<Ifpack_Preconditioner> PrecIC = Teuchos::rcp( Factory.Create("IC", &*A) ); Teuchos::ParameterList List; //List.get("fact: ict level-of-fill", 2.); //List.get("fact: drop tolerance", 0.3333); //List.get("fact: absolute threshold", 0.00123); //List.get("fact: relative threshold", 0.9876); //List.get("fact: relaxation value", 0.0); IFPACK_CHK_ERR(PrecIC->SetParameters(List)); IFPACK_CHK_ERR(PrecIC->Compute()); // Here we create an AztecOO object LHS->PutScalar(0.0); //AztecOO solver; solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_cg); solver.SetPrecOperator(&*PrecIC); solver.SetAztecOption(AZ_output, 16); solver.Iterate(maxIter, tol); int ICIters = solver.NumIters(); //cout << "Ifpack_IC iterations: " << ICIters << endl; // Compare to no preconditioning if (ICIters > Iters/2) IFPACK_CHK_ERR(-1); #if 0 ////////////////////////////////////////////////////// // Same test with Ifpack_ICT // This is another threshold Cholesky Teuchos::RefCountPtr<Ifpack_Preconditioner> PrecICT = Teuchos::rcp( Factory.Create("ICT", &*A) ); //Teuchos::ParameterList List; //List.get("fact: level-of-fill", 2); //List.get("fact: drop tolerance", 0.3333); //List.get("fact: absolute threshold", 0.00123); //List.get("fact: relative threshold", 0.9876); //List.get("fact: relaxation value", 0.0); IFPACK_CHK_ERR(PrecICT->SetParameters(List)); IFPACK_CHK_ERR(PrecICT->Compute()); // Here we create an AztecOO object LHS->PutScalar(0.0); solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_cg); solver.SetPrecOperator(&*PrecICT); solver.SetAztecOption(AZ_output, 16); solver.Iterate(maxIter, tol); int ICTIters = solver.NumIters(); //cout << "Ifpack_ICT iterations: " << ICTIters << endl; // Compare to no preconditioning if (ICTIters > Iters/2) IFPACK_CHK_ERR(-1); #endif #ifdef HAVE_MPI MPI_Finalize() ; #endif return(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm (MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int MyPID = Comm.MyPID(); bool verbose = false; if (MyPID==0) verbose = true; Teuchos::ParameterList GaleriList; int nx = 30; GaleriList.set("nx", nx); GaleriList.set("ny", nx * Comm.NumProc()); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Teuchos::RefCountPtr<Epetra_Map> Map = Teuchos::rcp( Galeri::CreateMap("Cartesian2D", Comm, GaleriList) ); Teuchos::RefCountPtr<Epetra_CrsMatrix> A = Teuchos::rcp( Galeri::CreateCrsMatrix("Laplace2D", &*Map, GaleriList) ); Teuchos::RefCountPtr<Epetra_MultiVector> LHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) ); Teuchos::RefCountPtr<Epetra_MultiVector> RHS = Teuchos::rcp( new Epetra_MultiVector(*Map, 1) ); LHS->PutScalar(0.0); RHS->Random(); // ============================ // // Construct ILU preconditioner // // ---------------------------- // // I wanna test funky values to be sure that they have the same // influence on the algorithms, both old and new int LevelFill = 2; double DropTol = 0.3333; double Athresh = 0.0123; double Rthresh = 0.9876; double Relax = 0.1; int Overlap = 2; Teuchos::RefCountPtr<Ifpack_IlukGraph> Graph; Teuchos::RefCountPtr<Ifpack_CrsRiluk> RILU; Graph = Teuchos::rcp( new Ifpack_IlukGraph(A->Graph(), LevelFill, Overlap) ); int ierr; ierr = Graph->ConstructFilledGraph(); IFPACK_CHK_ERR(ierr); RILU = Teuchos::rcp( new Ifpack_CrsRiluk(*Graph) ); RILU->SetAbsoluteThreshold(Athresh); RILU->SetRelativeThreshold(Rthresh); RILU->SetRelaxValue(Relax); int initerr = RILU->InitValues(*A); if (initerr!=0) cout << Comm << "*ERR* InitValues = " << initerr; RILU->Factor(); // Define label for printing out during the solve phase string label = "Ifpack_CrsRiluk Preconditioner: LevelFill = " + toString(LevelFill) + " Overlap = " + toString(Overlap) + " Athresh = " + toString(Athresh) + " Rthresh = " + toString(Rthresh); // Here we create an AztecOO object LHS->PutScalar(0.0); int Niters = 1200; AztecOO solver; solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_gmres); solver.SetPrecOperator(&*RILU); solver.SetAztecOption(AZ_output, 16); solver.Iterate(Niters, 5.0e-5); int OldIters = solver.NumIters(); // now rebuild the same preconditioner using RILU, we expect the same // number of iterations Ifpack Factory; Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec = Teuchos::rcp( Factory.Create("ILU", &*A, Overlap) ); Teuchos::ParameterList List; List.get("fact: level-of-fill", LevelFill); List.get("fact: drop tolerance", DropTol); List.get("fact: absolute threshold", Athresh); List.get("fact: relative threshold", Rthresh); List.get("fact: relax value", Relax); IFPACK_CHK_ERR(Prec->SetParameters(List)); IFPACK_CHK_ERR(Prec->Compute()); // Here we create an AztecOO object LHS->PutScalar(0.0); solver.SetUserMatrix(&*A); solver.SetLHS(&*LHS); solver.SetRHS(&*RHS); solver.SetAztecOption(AZ_solver,AZ_gmres); solver.SetPrecOperator(&*Prec); solver.SetAztecOption(AZ_output, 16); solver.Iterate(Niters, 5.0e-5); int NewIters = solver.NumIters(); if (OldIters != NewIters) IFPACK_CHK_ERR(-1); #ifdef HAVE_IFPACK_SUPERLU // Now test w/ SuperLU's ILU, if we've got it Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec2 = Teuchos::rcp( Factory.Create("SILU", &*A,0) ); Teuchos::ParameterList SList; SList.set("fact: drop tolerance",1e-4); SList.set("fact: zero pivot threshold",.1); SList.set("fact: maximum fill factor",10.0); // NOTE: There is a bug in SuperLU 4.0 which will crash the code if the maximum fill factor is set too low. // This bug was reported to Sherry Li on 4/8/10. SList.set("fact: silu drop rule",9); IFPACK_CHK_ERR(Prec2->SetParameters(SList)); IFPACK_CHK_ERR(Prec2->Compute()); LHS->PutScalar(0.0); solver.SetPrecOperator(&*Prec2); solver.Iterate(Niters, 5.0e-5); Prec2->Print(cout); #endif #ifdef HAVE_MPI MPI_Finalize() ; #endif return(EXIT_SUCCESS); }