void TrilinosPreconditioner<T>::compute() { Ifpack_Preconditioner * ifpack = NULL; #ifdef LIBMESH_HAVE_ML ML_Epetra::MultiLevelPreconditioner * ml = NULL; #endif switch (this->_preconditioner_type) { // IFPACK preconditioners case ILU_PRECOND: case SOR_PRECOND: ifpack = dynamic_cast<Ifpack_Preconditioner *>(_prec); ifpack->Compute(); break; #ifdef LIBMESH_HAVE_ML // ML preconditioners case AMG_PRECOND: ml = dynamic_cast<ML_Epetra::MultiLevelPreconditioner *>(_prec); ml->ComputePreconditioner(); break; #endif default: // no nothing here break; } }
void TrilinosPreconditioner<T>::set_preconditioner_type (const PreconditionerType & preconditioner_type) { Ifpack_Preconditioner * pc = NULL; #ifdef LIBMESH_HAVE_ML ML_Epetra::MultiLevelPreconditioner * ml = NULL; #endif switch (preconditioner_type) { case IDENTITY_PRECOND: // pc = new Ifpack_DiagPreconditioner(); break; case CHOLESKY_PRECOND: break; case ICC_PRECOND: break; case ILU_PRECOND: pc = new Ifpack_ILU(_mat); pc->SetParameters(_param_list); pc->Initialize(); _prec = pc; break; case LU_PRECOND: break; case ASM_PRECOND: break; case JACOBI_PRECOND: break; case BLOCK_JACOBI_PRECOND: break; case SOR_PRECOND: break; case EISENSTAT_PRECOND: break; #ifdef LIBMESH_HAVE_ML case AMG_PRECOND: ml = new ML_Epetra::MultiLevelPreconditioner(*_mat, _param_list, false);; _prec = ml; break; #endif default: libMesh::err << "ERROR: Unsupported Trilinos Preconditioner: " << preconditioner_type << std::endl << "Continuing with Trilinos defaults" << std::endl; } }
int ML_Self_Solve(void * Self_Handle, double * x, double * rhs ) { Ifpack_Preconditioner* Prec = (Ifpack_Preconditioner *)Self_Handle; Epetra_Vector Erhs(View, Prec->OperatorRangeMap(), rhs); Epetra_Vector Ex(View, Prec->OperatorDomainMap(), x); Prec->ApplyInverse(Erhs,Ex); return 0; } /* ML_Self_Solve */
void ML_Self_Destroy(void * Self_Handle) { Ifpack_Preconditioner* Prec = (Ifpack_Preconditioner *)Self_Handle; if (ML_Get_PrintLevel() > 8) cout << *Prec; const Epetra_CrsMatrix *Temp=dynamic_cast<const Epetra_CrsMatrix*>(&Prec->Matrix()); if(!Temp) delete &(Prec->Matrix()); // Note: Don't delete CrsMatrices, because we don't create those... delete Prec; } /* ML_Self_Destroy */
void TrilinosPreconditioner<T>::compute() { #ifdef LIBMESH_TRILINOS_HAVE_IFPACK Ifpack_Preconditioner * ifpack = libmesh_nullptr; #endif #ifdef LIBMESH_TRILINOS_HAVE_ML ML_Epetra::MultiLevelPreconditioner * ml = libmesh_nullptr; #endif switch (this->_preconditioner_type) { #ifdef LIBMESH_TRILINOS_HAVE_IFPACK // IFPACK preconditioners case ILU_PRECOND: case SOR_PRECOND: ifpack = dynamic_cast<Ifpack_Preconditioner *>(_prec); ifpack->Compute(); break; #endif #ifdef LIBMESH_TRILINOS_HAVE_ML // ML preconditioners case AMG_PRECOND: ml = dynamic_cast<ML_Epetra::MultiLevelPreconditioner *>(_prec); ml->ComputePreconditioner(); break; #endif default: // If we made it here, there were no TrilinosPreconditioners // active, so that's probably an error. libmesh_error_msg("ERROR: No valid TrilinosPreconditioners available!"); break; } }
int ML_Self_Gen(ML *ml, int Overlap, int curr_level, Teuchos::ParameterList& List, const Epetra_Comm& Comm, void ** Self_Handle) { ML_Operator *Ke = &(ml->Amat[curr_level]); Ifpack_Preconditioner* Prec; // If we have an underlying Epetra_CrsMatrix, send that to Ifpack... if(Ke && Ke->getrow && Ke->getrow->func_ptr==ML_Epetra_CrsMatrix_getrow){ Epetra_CrsMatrix *Acrs=(Epetra_CrsMatrix *) ML_Get_MyGetrowData(Ke); Prec = new Ifpack_AdditiveSchwarz<Ifpack_ML>(Acrs, Overlap); } else{ // Else, create the wrapper from ML_Operator to Epetra_RowMatrix // (ML_Epetra::RowMatrix). This is a cheap conversion RowMatrix* Self_Matrix = new RowMatrix(Ke, &Comm); assert (Self_Matrix != 0); Prec = new Ifpack_AdditiveSchwarz<Ifpack_ML>(Self_Matrix, Overlap); } assert (Prec != 0); List.set("zero starting solution", true); List.set("schwarz: compute condest", false); #ifdef IFPACK_NODE_AWARE_CODE ML_NODE_ID = List.get("ML node id",-1); #endif Prec->SetParameters(List); ML_CHK_ERR(Prec->Initialize()); ML_CHK_ERR(Prec->Compute()); *Self_Handle = (void *)Prec; return 0; } /* ML_Self_Gen */
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv, 0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif int nProcs, myPID ; Teuchos::ParameterList pLUList ; // ParaLU parameters Teuchos::ParameterList isoList ; // Isorropia parameters Teuchos::ParameterList shyLUList ; // shyLU parameters Teuchos::ParameterList ifpackList ; // shyLU parameters string ipFileName = "ShyLU.xml"; // TODO : Accept as i/p nProcs = mpiSession.getNProc(); myPID = Comm.MyPID(); if (myPID == 0) { cout <<"Parallel execution: nProcs="<< nProcs << endl; } // =================== Read input xml file ============================= Teuchos::updateParametersFromXmlFile(ipFileName, &pLUList); isoList = pLUList.sublist("Isorropia Input"); shyLUList = pLUList.sublist("ShyLU Input"); shyLUList.set("Outer Solver Library", "AztecOO"); // Get matrix market file name string MMFileName = Teuchos::getParameter<string>(pLUList, "mm_file"); string prec_type = Teuchos::getParameter<string>(pLUList, "preconditioner"); int maxiters = Teuchos::getParameter<int>(pLUList, "Outer Solver MaxIters"); double tol = Teuchos::getParameter<double>(pLUList, "Outer Solver Tolerance"); string rhsFileName = pLUList.get<string>("rhs_file", ""); if (myPID == 0) { cout << "Input :" << endl; cout << "ParaLU params " << endl; pLUList.print(std::cout, 2, true, true); cout << "Matrix market file name: " << MMFileName << endl; } // ==================== Read input Matrix ============================== Epetra_CrsMatrix *A; Epetra_MultiVector *b1; int err = EpetraExt::MatrixMarketFileToCrsMatrix(MMFileName.c_str(), Comm, A); //EpetraExt::MatlabFileToCrsMatrix(MMFileName.c_str(), Comm, A); //assert(err != 0); //cout <<"Done reading the matrix"<< endl; int n = A->NumGlobalRows(); //cout <<"n="<< n << endl; // Create input vectors Epetra_Map vecMap(n, 0, Comm); if (rhsFileName != "") { err = EpetraExt::MatrixMarketFileToMultiVector(rhsFileName.c_str(), vecMap, b1); } else { b1 = new Epetra_MultiVector(vecMap, 1, false); b1->PutScalar(1.0); } Epetra_MultiVector x(vecMap, 1); //cout << "Created the vectors" << endl; // Partition the matrix with hypergraph partitioning and redisstribute Isorropia::Epetra::Partitioner *partitioner = new Isorropia::Epetra::Partitioner(A, isoList, false); partitioner->partition(); Isorropia::Epetra::Redistributor rd(partitioner); Epetra_CrsMatrix *newA; Epetra_MultiVector *newX, *newB; rd.redistribute(*A, newA); delete A; A = newA; rd.redistribute(x, newX); rd.redistribute(*b1, newB); Epetra_LinearProblem problem(A, newX, newB); AztecOO solver(problem); ifpackList ; Ifpack_Preconditioner *prec; ML_Epetra::MultiLevelPreconditioner *MLprec; if (prec_type.compare("ShyLU") == 0) { prec = new Ifpack_ShyLU(A); prec->SetParameters(shyLUList); prec->Initialize(); prec->Compute(); //(dynamic_cast<Ifpack_ShyLU *>(prec))->JustTryIt(); //cout << " Going to set it in solver" << endl ; solver.SetPrecOperator(prec); //cout << " Done setting the solver" << endl ; } else if (prec_type.compare("ILU") == 0) { ifpackList.set( "fact: level-of-fill", 1 ); prec = new Ifpack_ILU(A); prec->SetParameters(ifpackList); prec->Initialize(); prec->Compute(); solver.SetPrecOperator(prec); } else if (prec_type.compare("ILUT") == 0) { ifpackList.set( "fact: ilut level-of-fill", 2 ); ifpackList.set( "fact: drop tolerance", 1e-8); prec = new Ifpack_ILUT(A); prec->SetParameters(ifpackList); prec->Initialize(); prec->Compute(); solver.SetPrecOperator(prec); } else if (prec_type.compare("ML") == 0) { Teuchos::ParameterList mlList; // TODO : Take it from i/p MLprec = new ML_Epetra::MultiLevelPreconditioner(*A, mlList, true); solver.SetPrecOperator(MLprec); } solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetMatrixName(333); //solver.SetAztecOption(AZ_output, 1); //solver.SetAztecOption(AZ_conv, AZ_Anorm); //cout << "Going to iterate for the global problem" << endl; solver.Iterate(maxiters, tol); // compute ||Ax - b|| double Norm; Epetra_MultiVector Ax(vecMap, 1); Epetra_MultiVector *newAx; rd.redistribute(Ax, newAx); A->Multiply(false, *newX, *newAx); newAx->Update(1.0, *newB, -1.0); newAx->Norm2(&Norm); double ANorm = A->NormOne(); cout << "|Ax-b |/|A| = " << Norm/ANorm << endl; delete newAx; if (prec_type.compare("ML") == 0) { delete MLprec; } else { delete prec; } delete b1; delete newX; delete newB; delete A; delete partitioner; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif Galeri::core::Workspace::setNumDimensions(3); Galeri::grid::Loadable domain, boundary; int numGlobalElementsX = 2 * comm.NumProc(); int numGlobalElementsY = 2; int numGlobalElementsZ = 2; int mx = comm.NumProc(); int my = 1; int mz = 1; Galeri::grid::Generator:: getCubeWithHexs(comm, numGlobalElementsX, numGlobalElementsY, numGlobalElementsZ, mx, my, mz, domain, boundary); Epetra_Map matrixMap(domain.getNumGlobalVertices(), 0, comm); Epetra_FECrsMatrix A(Copy, matrixMap, 0); Epetra_FEVector LHS(matrixMap); Epetra_FEVector RHS(matrixMap); Galeri::problem::ScalarLaplacian<Laplacian> problem("Hex", 1, 8); problem.integrate(domain, A, RHS); LHS.PutScalar(0.0); problem.imposeDirichletBoundaryConditions(boundary, A, RHS, LHS); // ============================================================ // // Solving the linear system is the next step, using the IFPACK // // factory. This is done by using the IFPACK factory, then // // asking for IC preconditioner, and setting few parameters // // using a Teuchos::ParameterList. // // ============================================================ // Ifpack Factory; Ifpack_Preconditioner* Prec = Factory.Create("IC", &A, 0); Teuchos::ParameterList list; list.set("fact: level-of-fill", 1); IFPACK_CHK_ERR(Prec->SetParameters(list)); IFPACK_CHK_ERR(Prec->Initialize()); IFPACK_CHK_ERR(Prec->Compute()); Epetra_LinearProblem linearProblem(&A, &LHS, &RHS); AztecOO solver(linearProblem); solver.SetAztecOption(AZ_solver, AZ_cg); solver.SetPrecOperator(Prec); solver.Iterate(1550, 1e-9); // visualization using MEDIT -- a VTK module is available as well Galeri::viz::MEDIT::write(domain, "sol", LHS); // now compute the norm of the solution problem.computeNorms(domain, LHS); #ifdef HAVE_MPI MPI_Finalize(); #endif }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI Teuchos::GlobalMPISession mpiSession(&argc, &argv, 0); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif typedef double ST; typedef Teuchos::ScalarTraits<ST> SCT; typedef SCT::magnitudeType MT; typedef Epetra_MultiVector MV; typedef Epetra_Operator OP; typedef Belos::MultiVecTraits<ST,MV> MVT; typedef Belos::OperatorTraits<ST,MV,OP> OPT; using Teuchos::RCP; using Teuchos::rcp; bool success = true; string pass = "******"; string fail = "End Result: TEST FAILED"; bool verbose = false, proc_verbose = true; bool leftprec = false; // left preconditioning or right. int frequency = -1; // frequency of status test output. int blocksize = 1; // blocksize int numrhs = 1; // number of right-hand sides to solve for int maxrestarts = 15; // maximum number of restarts allowed int maxsubspace = 25; // maximum number of blocks the solver can use // for the subspace char file_name[100]; int nProcs, myPID ; Teuchos::RCP <Teuchos::ParameterList> pLUList ; // ParaLU parameters Teuchos::ParameterList isoList ; // Isorropia parameters Teuchos::ParameterList shyLUList ; // ShyLU parameters string ipFileName = "ShyLU.xml"; // TODO : Accept as i/p #ifdef HAVE_MPI nProcs = mpiSession.getNProc(); myPID = Comm.MyPID(); #else nProcs = 1; myPID = 0; #endif if (myPID == 0) { cout <<"Parallel execution: nProcs="<< nProcs << endl; } // =================== Read input xml file ============================= pLUList = Teuchos::getParametersFromXmlFile(ipFileName); isoList = pLUList->sublist("Isorropia Input"); shyLUList = pLUList->sublist("ShyLU Input"); shyLUList.set("Outer Solver Library", "Belos"); // Get matrix market file name string MMFileName = Teuchos::getParameter<string>(*pLUList, "mm_file"); string prec_type = Teuchos::getParameter<string>(*pLUList, "preconditioner"); int maxiters = Teuchos::getParameter<int>(*pLUList, "Outer Solver MaxIters"); MT tol = Teuchos::getParameter<double>(*pLUList, "Outer Solver Tolerance"); string rhsFileName = pLUList->get<string>("rhs_file", ""); int maxFiles = pLUList->get<int>("Maximum number of files to read in", 1); int startFile = pLUList->get<int>("Number of initial file", 1); int file_number = startFile; if (myPID == 0) { cout << "Input :" << endl; cout << "ParaLU params " << endl; pLUList->print(std::cout, 2, true, true); cout << "Matrix market file name: " << MMFileName << endl; } if (maxFiles > 1) { MMFileName += "%d.mm"; sprintf( file_name, MMFileName.c_str(), file_number ); } else { strcpy( file_name, MMFileName.c_str()); } // ==================== Read input Matrix ============================== Epetra_CrsMatrix *A; Epetra_MultiVector *b1; int err = EpetraExt::MatrixMarketFileToCrsMatrix(file_name, Comm, A); if (err != 0 && myPID == 0) { cout << "Matrix file could not be read in!!!, info = "<< err << endl; success = false; } int n = A->NumGlobalRows(); // ==================== Read input rhs ============================== if (rhsFileName != "" && maxFiles > 1) { rhsFileName += "%d.mm"; sprintf( file_name, rhsFileName.c_str(), file_number ); } else { strcpy( file_name, rhsFileName.c_str()); } Epetra_Map vecMap(n, 0, Comm); bool allOneRHS = false; if (rhsFileName != "") { err = EpetraExt::MatrixMarketFileToMultiVector(file_name, vecMap, b1); } else { b1 = new Epetra_MultiVector(vecMap, 1, false); b1->Random(); allOneRHS = true; } Epetra_MultiVector x(vecMap, 1); // Partition the matrix with hypergraph partitioning and redisstribute Isorropia::Epetra::Partitioner *partitioner = new Isorropia::Epetra::Partitioner(A, isoList, false); partitioner->partition(); Isorropia::Epetra::Redistributor rd(partitioner); Epetra_CrsMatrix *newA; Epetra_MultiVector *newX, *newB; rd.redistribute(*A, newA); delete A; A = newA; RCP<Epetra_CrsMatrix> rcpA(A, false); rd.redistribute(x, newX); rd.redistribute(*b1, newB); delete b1; RCP<Epetra_MultiVector> rcpx (newX, false); RCP<Epetra_MultiVector> rcpb (newB, false); //OPT::Apply(*rcpA, *rcpx, *rcpb ); Epetra_CrsMatrix *iterA = 0; Epetra_CrsMatrix *redistA = 0; Epetra_MultiVector *iterb1 = 0; Ifpack_Preconditioner *prec; ML_Epetra::MultiLevelPreconditioner *MLprec; //#ifdef TIMING_OUTPUT Teuchos::Time ftime("solve time"); //#endif while(file_number < maxFiles+startFile) { if (prec_type.compare("ShyLU") == 0) { if (file_number == startFile) { //#ifdef TIMING_OUTPUT ftime.start(); //#endif prec = new Ifpack_ShyLU(A); #ifdef HAVE_IFPACK_DYNAMIC_FACTORY Teuchos::ParameterList shyluParameters; shyluParameters.set<Teuchos::ParameterList>("ShyLU list", shyLUList); prec->SetParameters(shyluParameters); #else prec->SetParameters(shyLUList); #endif prec->Initialize(); //#ifdef TIMING_OUTPUT ftime.stop(); //#endif } //#ifdef TIMING_OUTPUT ftime.start(); //#endif prec->Compute(); //#ifdef TIMING_OUTPUT ftime.stop(); //#endif //cout << " Going to set it in solver" << endl ; //solver.SetPrecOperator(prec); //cout << " Done setting the solver" << endl ; } else if (prec_type.compare("ILU") == 0) { prec = new Ifpack_ILU(A); prec->Initialize(); prec->Compute(); //solver.SetPrecOperator(prec); } else if (prec_type.compare("ILUT") == 0) { prec = new Ifpack_ILUT(A); prec->Initialize(); prec->Compute(); //solver.SetPrecOperator(prec); } else if (prec_type.compare("ML") == 0) { Teuchos::ParameterList mlList; // TODO : Take it from i/p MLprec = new ML_Epetra::MultiLevelPreconditioner(*A, mlList, true); //solver.SetPrecOperator(MLprec); } RCP<Ifpack_Preconditioner> rcpPrec(prec, false); RCP<Belos::EpetraPrecOp> belosPrec = rcp(new Belos::EpetraPrecOp(rcpPrec)); const int NumGlobalElements = rcpb->GlobalLength(); Teuchos::ParameterList belosList; //belosList.set( "Flexible Gmres", true ); belosList.set( "Num Blocks", maxsubspace );// Maximum number of blocks in Krylov factorization belosList.set( "Block Size", blocksize ); // Blocksize to be used by iterative solver belosList.set( "Maximum Iterations", maxiters ); // Maximum number of iterations allowed belosList.set( "Maximum Restarts", maxrestarts );// Maximum number of restarts allowed belosList.set( "Convergence Tolerance", tol ); // Relative convergence tolerance requested if (numrhs > 1) { belosList.set( "Show Maximum Residual Norm Only", true ); // Show only the maximum residual norm } if (verbose) { belosList.set( "Verbosity", Belos::Errors + Belos::Warnings + Belos::TimingDetails + Belos::StatusTestDetails ); if (frequency > 0) belosList.set( "Output Frequency", frequency ); } else belosList.set( "Verbosity", Belos::Errors + Belos::Warnings ); // // *******Construct a preconditioned linear problem******** // rcpx->PutScalar(0.0); RCP<Belos::LinearProblem<double,MV,OP> > problem = rcp( new Belos::LinearProblem<double,MV,OP>( rcpA, rcpx, rcpb ) ); if (leftprec) { problem->setLeftPrec( belosPrec ); } else { problem->setRightPrec( belosPrec ); } bool set = problem->setProblem(); if (set == false) { if (proc_verbose) { cout << endl << "ERROR: Belos::LinearProblem failed to set up correctly!" << endl; } cout << fail << endl; success = false; return -1; } // Create an iterative solver manager. RCP< Belos::SolverManager<double,MV,OP> > solver = rcp( new Belos::BlockGmresSolMgr<double,MV,OP>(problem, rcp(&belosList,false))); // // ******************************************************************* // *************Start the block Gmres iteration************************* // ******************************************************************* // if (proc_verbose) { cout << std::endl << std::endl; cout << "Dimension of matrix: " << NumGlobalElements << endl; cout << "Number of right-hand sides: " << numrhs << endl; cout << "Block size used by solver: " << blocksize << endl; cout << "Number of restarts allowed: " << maxrestarts << endl; cout << "Max number of Gmres iterations per restart cycle: " << maxiters << endl; cout << "Relative residual tolerance: " << tol << endl; cout << endl; } if(tol > 1e-5) { success = false; } // // Perform solve // //#ifdef TIMING_OUTPUT ftime.start(); //#endif // mfh 26 Mar 2015: Don't introduce a variable (like 'ret') // unless you plan to use it. The commented-out code causes a // build warning. // //Belos::ReturnType ret = solver->solve(); solver->solve (); //#ifdef TIMING_OUTPUT ftime.stop(); //#endif // // Get the number of iterations for this solve. // int numIters = solver->getNumIters(); if (proc_verbose) { cout << "Number of iterations performed for this solve: " << numIters << endl; } // // Compute actual residuals. // //bool badRes = false; // unused std::vector<double> actual_resids( numrhs ); std::vector<double> rhs_norm( numrhs ); Epetra_MultiVector resid((*rcpA).RowMap(), numrhs); OPT::Apply( *rcpA, *rcpx, resid ); MVT::MvAddMv( -1.0, resid, 1.0, *rcpb, resid ); MVT::MvNorm( resid, actual_resids ); MVT::MvNorm( *rcpb, rhs_norm ); if (proc_verbose) { cout<< "------ Actual Residuals (normalized) -------"<<endl; for ( int i=0; i<numrhs; i++) { double actRes = actual_resids[i]/rhs_norm[i]; std::cout<<"Problem "<<i<<" : \t"<< actRes <<std::endl; if (actRes > tol) { //badRes = true; // unused success = false; } } } file_number++; if (file_number >= maxFiles+startFile) { break; } else { sprintf(file_name, MMFileName.c_str(), file_number); if (redistA != NULL) delete redistA; // Load the new matrix err = EpetraExt::MatrixMarketFileToCrsMatrix(file_name, Comm, iterA); if (err != 0) { if (myPID == 0) { cout << "Could not open file: "<< file_name << endl; } success = false; } else { rd.redistribute(*iterA, redistA); delete iterA; InitMatValues(*redistA, A); } // Load the new rhs if (!allOneRHS) { sprintf(file_name, rhsFileName.c_str(), file_number); if (iterb1 != NULL) delete iterb1; err = EpetraExt::MatrixMarketFileToMultiVector(file_name, vecMap, b1); if (err != 0) { if (myPID==0) { cout << "Could not open file: "<< file_name << endl; success = false; } } else { rd.redistribute(*b1, iterb1); delete b1; InitMVValues( *iterb1, newB ); } } } } //#ifdef TIMING_OUTPUT cout << "Time to solve: " << ftime.totalElapsedTime() << endl; if(success) { cout << pass << endl; } else { cout << fail << endl; } //#endif if (redistA != NULL) delete redistA; if (iterb1 != NULL) delete iterb1; if (prec_type.compare("ML") == 0) { delete MLprec; } else { delete prec; } delete newX; delete newB; delete A; delete partitioner; }
void TrilinosPreconditioner<T>::set_preconditioner_type (const PreconditionerType & preconditioner_type) { #ifdef LIBMESH_TRILINOS_HAVE_IFPACK Ifpack_Preconditioner * pc = libmesh_nullptr; #endif #ifdef LIBMESH_TRILINOS_HAVE_ML ML_Epetra::MultiLevelPreconditioner * ml = libmesh_nullptr; #endif switch (preconditioner_type) { case IDENTITY_PRECOND: // pc = new Ifpack_DiagPreconditioner(); break; case CHOLESKY_PRECOND: break; case ICC_PRECOND: break; #ifdef LIBMESH_TRILINOS_HAVE_IFPACK case ILU_PRECOND: pc = new Ifpack_ILU(_mat); pc->SetParameters(_param_list); pc->Initialize(); _prec = pc; break; #endif case LU_PRECOND: break; case ASM_PRECOND: break; case JACOBI_PRECOND: break; case BLOCK_JACOBI_PRECOND: break; case SOR_PRECOND: break; case EISENSTAT_PRECOND: break; #ifdef LIBMESH_TRILINOS_HAVE_ML case AMG_PRECOND: ml = new ML_Epetra::MultiLevelPreconditioner(*_mat, _param_list, false);; _prec = ml; break; #endif default: libmesh_error_msg("ERROR: Unsupported Trilinos Preconditioner: " << preconditioner_type << "\nContinuing with Trilinos defaults"); } }
double Ifpack_Condest(const Ifpack_Preconditioner& IFP, const Ifpack_CondestType CT, const int MaxIters, const double Tol, Epetra_RowMatrix* Matrix) { double ConditionNumberEstimate = -1.0; if (CT == Ifpack_Cheap) { // Create a vector with all values equal to one Epetra_Vector Ones(IFP.OperatorDomainMap()); Ones.PutScalar(1.0); // Create the vector of results Epetra_Vector OnesResult(IFP.OperatorRangeMap()); // Compute the effect of the solve on the vector of ones IFPACK_CHK_ERR(IFP.ApplyInverse(Ones, OnesResult)); // Make all values non-negative IFPACK_CHK_ERR(OnesResult.Abs(OnesResult)); // Get the maximum value across all processors IFPACK_CHK_ERR(OnesResult.MaxValue(&ConditionNumberEstimate)); } else if (CT == Ifpack_CG) { #ifdef HAVE_IFPACK_AZTECOO if (Matrix == 0) Matrix = (Epetra_RowMatrix*)&(IFP.Matrix()); Epetra_Vector LHS(IFP.OperatorDomainMap()); LHS.PutScalar(0.0); Epetra_Vector RHS(IFP.OperatorRangeMap()); RHS.Random(); Epetra_LinearProblem Problem; Problem.SetOperator(Matrix); Problem.SetLHS(&LHS); Problem.SetRHS(&RHS); AztecOO Solver(Problem); Solver.SetAztecOption(AZ_output,AZ_none); Solver.SetAztecOption(AZ_solver,AZ_cg_condnum); Solver.Iterate(MaxIters,Tol); const double* status = Solver.GetAztecStatus(); ConditionNumberEstimate = status[AZ_condnum]; #endif } else if (CT == Ifpack_GMRES) { #ifdef HAVE_IFPACK_AZTECOO if (Matrix == 0) Matrix = (Epetra_RowMatrix*)&(IFP.Matrix()); Epetra_Vector LHS(IFP.OperatorDomainMap()); LHS.PutScalar(0.0); Epetra_Vector RHS(IFP.OperatorRangeMap()); RHS.Random(); Epetra_LinearProblem Problem; Problem.SetOperator(Matrix); Problem.SetLHS(&LHS); Problem.SetRHS(&RHS); AztecOO Solver(Problem); Solver.SetAztecOption(AZ_solver,AZ_gmres_condnum); Solver.SetAztecOption(AZ_output,AZ_none); // the following can be problematic for large problems, // but any restart would destroy useful information about // the condition number. Solver.SetAztecOption(AZ_kspace,MaxIters); Solver.Iterate(MaxIters,Tol); const double* status = Solver.GetAztecStatus(); ConditionNumberEstimate = status[AZ_condnum]; #endif } return(ConditionNumberEstimate); }