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; // 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(); // ============================ // // 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 Condest; Teuchos::RefCountPtr<Ifpack_CrsIct> ICT; ICT = Teuchos::rcp( new Ifpack_CrsIct(*A,DropTol,LevelFill) ); ICT->SetAbsoluteThreshold(0.00123); ICT->SetRelativeThreshold(0.9876); // Init values from A ICT->InitValues(*A); // compute the factors ICT->Factor(); // and now estimate the condition number ICT->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 string label = "Ifpack_CrsIct Preconditioner: LevelFill = " + toString(LevelFill) + " Overlap = 0"; ICT->SetLabel(label.c_str()); // 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_cg); solver.SetPrecOperator(&*ICT); solver.SetAztecOption(AZ_output, 16); solver.Iterate(Niters, 5.0e-5); int OldIters = solver.NumIters(); // now rebuild the same preconditioner using ICT, we expect the same // number of iterations Ifpack Factory; Teuchos::RefCountPtr<Ifpack_Preconditioner> Prec = Teuchos::rcp( Factory.Create("IC", &*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(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_cg); 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_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 // 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); }