int AmesosGenOp::Apply (const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { if (problem_ == NULL) { throw std::logic_error ("AmesosGenOp::Apply: problem_ is NULL"); } if (massMtx_.is_null ()) { throw std::logic_error ("AmesosGenOp::Apply: massMtx_ is null"); } if (solver_.is_null ()) { throw std::logic_error ("AmesosGenOp::Apply: solver_ is null"); } if (! useTranspose_) { // Storage for M*X Epetra_MultiVector MX (X.Map (), X.NumVectors ()); // Apply M*X massMtx_->Apply (X, MX); Y.PutScalar (0.0); // Set the LHS and RHS problem_->SetRHS (&MX); problem_->SetLHS (&Y); // Solve the linear system A*Y = MX solver_->Solve (); } else { // apply the transposed operator // Storage for A^{-T}*X Epetra_MultiVector ATX (X.Map (), X.NumVectors ()); Epetra_MultiVector tmpX = const_cast<Epetra_MultiVector&> (X); // Set the LHS and RHS problem_->SetRHS (&tmpX); problem_->SetLHS (&ATX); // Solve the linear system A^T*Y = X solver_->Solve (); // Apply M*ATX massMtx_->Apply (ATX, Y); } return 0; // the method completed correctly }
// ====================================================================== void Krylov(const Operator& A, const MultiVector& LHS, const MultiVector& RHS, const BaseOperator& Prec, Teuchos::ParameterList& List) { #ifndef HAVE_ML_AZTECOO std::cerr << "Please configure ML with --enable-aztecoo to use" << std::endl; std::cerr << "MLAPI Krylov solvers" << std::endl; exit(EXIT_FAILURE); #else if (LHS.GetNumVectors() != 1) ML_THROW("FIXME: only one vector is currently supported", -1); Epetra_LinearProblem Problem; const Epetra_RowMatrix& A_Epetra = *(A.GetRowMatrix()); Epetra_Vector LHS_Epetra(View,A_Epetra.OperatorDomainMap(), (double*)&(LHS(0))); Epetra_Vector RHS_Epetra(View,A_Epetra.OperatorRangeMap(), (double*)&(RHS(0))); // FIXME: this works only for Epetra-based operators Problem.SetOperator((const_cast<Epetra_RowMatrix*>(&A_Epetra))); Problem.SetLHS(&LHS_Epetra); Problem.SetRHS(&RHS_Epetra); AztecOO solver(Problem); EpetraBaseOperator Prec_Epetra(A_Epetra.OperatorDomainMap(),Prec); solver.SetPrecOperator(&Prec_Epetra); // get options from List int NumIters = List.get("krylov: max iterations", 1550); double Tol = List.get("krylov: tolerance", 1e-9); std::string type = List.get("krylov: type", "gmres"); int output = List.get("krylov: output level", GetPrintLevel()); // set options in `solver' if (type == "cg") solver.SetAztecOption(AZ_solver, AZ_cg); else if (type == "cg_condnum") solver.SetAztecOption(AZ_solver, AZ_cg_condnum); else if (type == "gmres") solver.SetAztecOption(AZ_solver, AZ_gmres); else if (type == "gmres_condnum") solver.SetAztecOption(AZ_solver, AZ_gmres_condnum); else if (type == "fixed point") solver.SetAztecOption(AZ_solver, AZ_fixed_pt); else ML_THROW("krylov: type has incorrect value (" + type + ")", -1); solver.SetAztecOption(AZ_output, output); solver.Iterate(NumIters, Tol); #endif }
int AmesosGenOp::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y ) const { if (!useTranspose_) { // Storage for M*X Epetra_MultiVector MX(X.Map(),X.NumVectors()); // Apply M*X massMtx_->Apply(X, MX); Y.PutScalar(0.0); // Set the LHS and RHS problem_->SetRHS(&MX); problem_->SetLHS(&Y); // Solve the linear system A*Y = MX solver_->Solve(); } else { // Storage for A^{-T}*X Epetra_MultiVector ATX(X.Map(),X.NumVectors()); Epetra_MultiVector tmpX = const_cast<Epetra_MultiVector&>(X); // Set the LHS and RHS problem_->SetRHS(&tmpX); problem_->SetLHS(&ATX); // Solve the linear system A^T*Y = X solver_->Solve(); // Apply M*ATX massMtx_->Apply(ATX, Y); } return 0; }
int AmesosBucklingOp::Apply(const Epetra_MultiVector& X, Epetra_MultiVector& Y ) const { // Storage for A*X Epetra_MultiVector AX(X.Map(),X.NumVectors()); // Apply A*X stiffMtx_->Apply(X, AX); Y.PutScalar(0.0); // Set the LHS and RHS problem_->SetRHS(&AX); problem_->SetLHS(&Y); // Solve the linear system (A-sigma*M)*Y = AX solver_->Solve(); return 0; }
int PartialFactorizationOneStep( const char* AmesosClass, const Epetra_Comm &Comm, bool transpose, bool verbose, Teuchos::ParameterList ParamList, Epetra_CrsMatrix *& Amat, double Rcond, int Steps ) { assert( Steps >= 0 && Steps < MaxNumSteps ) ; int iam = Comm.MyPID() ; int errors = 0 ; const Epetra_Map *RangeMap = transpose?&Amat->OperatorDomainMap():&Amat->OperatorRangeMap() ; const Epetra_Map *DomainMap = transpose?&Amat->OperatorRangeMap():&Amat->OperatorDomainMap() ; Epetra_Vector xexact(*DomainMap); Epetra_Vector x(*DomainMap); Epetra_Vector b(*RangeMap); Epetra_Vector bcheck(*RangeMap); Epetra_Vector difference(*DomainMap); Epetra_LinearProblem Problem; Amesos_BaseSolver* Abase ; Amesos Afactory; Abase = Afactory.Create( AmesosClass, Problem ) ; std::string AC = AmesosClass ; if ( AC == "Amesos_Mumps" ) { ParamList.set( "NoDestroy", true ); Abase->SetParameters( ParamList ) ; } double relresidual = 0 ; if ( Steps > 0 ) { // // Phase 1: Compute b = A' A' A xexact // Problem.SetOperator( Amat ); // // We only set transpose if we have to - this allows valgrind to check // that transpose is set to a default value before it is used. // if ( transpose ) OUR_CHK_ERR( Abase->SetUseTranspose( transpose ) ); // if (verbose) ParamList.set( "DebugLevel", 1 ); // if (verbose) ParamList.set( "OutputLevel", 1 ); if ( Steps > 1 ) { OUR_CHK_ERR( Abase->SetParameters( ParamList ) ); if ( Steps > 2 ) { xexact.Random(); xexact.PutScalar(1.0); // // Compute cAx = A' xexact // Amat->Multiply( transpose, xexact, b ) ; // b = A x2 = A A' A'' xexact #if 0 std::cout << __FILE__ << "::" << __LINE__ << "b = " << std::endl ; b.Print( std::cout ) ; std::cout << __FILE__ << "::" << __LINE__ << "xexact = " << std::endl ; xexact.Print( std::cout ) ; std::cout << __FILE__ << "::" << __LINE__ << "x = " << std::endl ; x.Print( std::cout ) ; #endif // // Phase 2: Solve A' A' A x = b // // // Solve A sAAx = b // Problem.SetLHS( &x ); Problem.SetRHS( &b ); OUR_CHK_ERR( Abase->SymbolicFactorization( ) ); if ( Steps > 2 ) { OUR_CHK_ERR( Abase->SymbolicFactorization( ) ); if ( Steps > 3 ) { OUR_CHK_ERR( Abase->NumericFactorization( ) ); if ( Steps > 4 ) { OUR_CHK_ERR( Abase->NumericFactorization( ) ); if ( Steps > 5 ) { OUR_CHK_ERR( Abase->Solve( ) ); if ( Steps > 6 ) { OUR_CHK_ERR( Abase->Solve( ) ); Amat->Multiply( transpose, x, bcheck ) ; // temp = A" x2 double norm_diff ; double norm_one ; difference.Update( 1.0, x, -1.0, xexact, 0.0 ) ; difference.Norm2( &norm_diff ) ; x.Norm2( &norm_one ) ; relresidual = norm_diff / norm_one ; if (iam == 0 ) { if ( relresidual * Rcond > 1e-16 ) { if (verbose) std::cout << __FILE__ << "::"<< __LINE__ << " norm( x - xexact ) / norm(x) = " << norm_diff /norm_one << std::endl ; errors += 1 ; } } } } } } } } } } delete Abase; return errors; }
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); }
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 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"); // Get matrix market file name string MMFileName = Teuchos::getParameter<string>(pLUList, "mm_file"); string prec_type = Teuchos::getParameter<string>(pLUList, "preconditioner"); 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; 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); Epetra_MultiVector x(vecMap, 1); Epetra_MultiVector b(vecMap, 1, false); b.PutScalar(1.0); // TODO : Accept it as input // 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(b, newB); Epetra_LinearProblem problem(A, newX, newB); Amesos Factory; char* SolverType = "Amesos_Klu"; bool IsAvailable = Factory.Query(SolverType); Epetra_LinearProblem *LP = new Epetra_LinearProblem(); LP->SetOperator(A); LP->SetLHS(newX); LP->SetRHS(newB); Amesos_BaseSolver *Solver = Factory.Create(SolverType, *LP); Solver->SymbolicFactorization(); Teuchos::Time ftime("setup time"); ftime.start(); Solver->NumericFactorization(); cout << "Numeric Factorization" << endl; Solver->Solve(); cout << "Solve done" << endl; ftime.stop(); cout << "Time to setup" << ftime.totalElapsedTime() << endl; // 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; delete newX; delete newB; delete A; delete partitioner; }