/*! * \brief Solve. */ void JacobiSolver::iterate( const int max_iters, const double tolerance ) { // Extract the linear problem. Epetra_CrsMatrix *A = dynamic_cast<Epetra_CrsMatrix*>( d_linear_problem->GetMatrix() ); Epetra_Vector *x = dynamic_cast<Epetra_Vector*>( d_linear_problem->GetLHS() ); const Epetra_Vector *b = dynamic_cast<Epetra_Vector*>( d_linear_problem->GetRHS() ); // Setup the residual. Epetra_Map row_map = A->RowMap(); Epetra_Vector residual( row_map ); // Iterate. Epetra_CrsMatrix H = buildH( A ); Epetra_Vector temp_vec( row_map ); d_num_iters = 0; double residual_norm = 1.0; double b_norm; b->NormInf( &b_norm ); double conv_crit = b_norm*tolerance; while ( residual_norm > conv_crit && d_num_iters < max_iters ) { H.Apply( *x, temp_vec ); x->Update( 1.0, temp_vec, 1.0, *b, 0.0 ); A->Apply( *x, temp_vec ); residual.Update( 1.0, *b, -1.0, temp_vec, 0.0 ); residual.NormInf( &residual_norm ); ++d_num_iters; } }
int power_method(bool TransA, Epetra_RowMatrix& A, Epetra_Vector& q, Epetra_Vector& z0, Epetra_Vector& resid, double* lambda, int niters, double tolerance, bool verbose) { // Fill z with random Numbers Epetra_Vector z(z0); // variable needed for iteration double normz, residual; int ierr = 1; for(int iter = 0; iter < niters; iter++) { z.Norm2(&normz); // Compute 2-norm of z q.Scale(1.0/normz, z); A.Multiply(TransA, q, z); // Compute z = A*q // SEGFAULT HAPPENS HERE q.Dot(z, lambda); // Approximate maximum eigenvaluE if(iter%100==0 || iter+1==niters) { resid.Update(1.0, z, -(*lambda), q, 0.0); // Compute A*q - lambda*q resid.Norm2(&residual); if(verbose) cout << "Iter = " << iter << " Lambda = " << *lambda << " Residual of A*q - lambda*q = " << residual << endl; } if(residual < tolerance) { ierr = 0; break; } } return(ierr); }
/*----------------------------------------------------------------------* | evaluate nonlinear function (public, derived) m.gee 3/06| *----------------------------------------------------------------------*/ bool NLNML::NLNML_CoarseLevelNoxInterface::computeF( const Epetra_Vector& x, Epetra_Vector& F, const FillType fillFlag) { bool err; if (!Level()) { err = fineinterface_->computeF(x,F,fillFlag); if (err==false) { cout << "**ERR**: NLNML::NLNML_CoarseLevelNoxInterface::computeF:\n" << "**ERR**: call to fine-userinterface returned false on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } } else { RefCountPtr<Epetra_Vector> Ffine = rcp(new Epetra_Vector(fineinterface_->getGraph()->RowMap(),false)); RefCountPtr<Epetra_Vector> xfine = rcp(prolong_this_to_fine(x)); err = fineinterface_->computeF(*xfine,*Ffine,fillFlag); if (err==false) { cout << "**ERR**: NLNML::NLNML_CoarseLevelNoxInterface::computeF:\n" << "**ERR**: call to fine-userinterface returned false on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } RefCountPtr<Epetra_Vector> Fcoarse = rcp(restrict_fine_to_this(*Ffine)); F.Scale(1.0,*Fcoarse); } if (isFAS()) F.Update(-1.0,*fxbar_,1.0,*fbar_,1.0); return err; }
int powerMethod (double & lambda, Epetra_CrsMatrix& A, const int niters, const double tolerance, const bool verbose) { // In the power iteration, z = A*q. Thus, q must be in the domain // of A, and z must be in the range of A. The residual vector is of // course in the range of A. Epetra_Vector q (A.OperatorDomainMap ()); Epetra_Vector z (A.OperatorRangeMap ()); Epetra_Vector resid (A.OperatorRangeMap ()); Epetra_Flops* counter = A.GetFlopCounter(); if (counter != 0) { q.SetFlopCounter(A); z.SetFlopCounter(A); resid.SetFlopCounter(A); } // Initialize the starting vector z with random data. z.Random(); double normz, residual; int ierr = 1; for (int iter = 0; iter < niters; ++iter) { z.Norm2 (&normz); // normz := ||z||_2 q.Scale (1.0/normz, z); // q := z / normz A.Multiply(false, q, z); // z := A * q q.Dot(z, &lambda); // lambda := dot (q, z) // Compute the residual vector and display status output every // 100 iterations, or if we have reached the maximum number of // iterations. if (iter % 100 == 0 || iter + 1 == niters) { resid.Update (1.0, z, -lambda, q, 0.0); // resid := A*q - lambda*q resid.Norm2 (&residual); // residual := ||resid||_2 if (verbose) cout << "Iter = " << iter << " Lambda = " << lambda << " Residual of A*q - lambda*q = " << residual << endl; } if (residual < tolerance) { // We've converged! ierr = 0; break; } } return ierr; }
void Stokhos::ProductEpetraVector:: assignToBlockVector(Epetra_Vector& v) const { if (this->size() > 0) { if (bv != Teuchos::null) v.Update(1.0, *bv, 0.0); else { EpetraExt::BlockVector block_v(View, *coeff_map, v); for (int i=0; i<this->size(); i++) *(block_v.GetBlock(i)) = *(coeff_[i]); } } }
/*----------------------------------------------------------------------* | Constructor (public) m.gee 12/04| | IMPORTANT: | | No matter on which level we are here, the vector xfine is ALWAYS | | a fine grid vector here! | *----------------------------------------------------------------------*/ ML_NOX::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel(int level, int nlevel, int plevel, ML* ml, ML_Aggregate* ag, Epetra_CrsMatrix** P, ML_NOX::Ml_Nox_Fineinterface& interface, const Epetra_Comm& comm, const Epetra_Vector& xfine, double fd_alpha, double fd_beta, bool fd_centered, bool isDiagonalOnly, int bsize) : fineinterface_(interface), comm_(comm) { level_ = level; nlevel_ = nlevel; ml_printlevel_ = plevel; ml_ = ml; ag_ = ag; fd_alpha_ = fd_alpha; fd_beta_ = fd_beta; fd_centered_ = fd_centered; isDiagonalOnly_ = isDiagonalOnly; A_ = 0; coarseinterface_= 0; bsize_ = bsize; // we need the graph of the operator on this level. On the fine grid we can just ask the // fineinterface for it, on the coarser levels it has to be extracted from the ML-hierachy if (level_==0) { // the Epetra_CrsGraph-copy-constructor shares data with the original one. // We want a really deep copy here so we cannot use it // graph_ will be given to the FiniteDifferencing class and will be destroyed by it graph_ = ML_NOX::deepcopy_graph(interface.getGraph()); } else { // Note that ML has no understanding of global indices, so it makes up new GIDs // (This also holds for the Prolongators P) Epetra_CrsMatrix* tmpMat = 0; int maxnnz = 0; double cputime = 0.0; ML_Operator2EpetraCrsMatrix(&(ml_->Amat[level_]), tmpMat, maxnnz, false, cputime); // copy the graph double t0 = GetClock(); graph_ = ML_NOX::deepcopy_graph(&(tmpMat->Graph())); // delete the copy of the Epetra_CrsMatrix if (tmpMat) delete tmpMat; tmpMat = 0; double t1 = GetClock(); if (ml_printlevel_ > 0 && 0 == comm_.MyPID()) cout << "matrixfreeML (level " << level_ << "): extraction/copy of Graph in " << cputime+t1-t0 << " sec\n" << " max-nonzeros in Graph: " << maxnnz << "\n"; } // create this levels coarse interface coarseinterface_ = new ML_NOX::Nox_CoarseProblem_Interface(fineinterface_,level_,ml_printlevel_, P,&(graph_->RowMap()),nlevel_); // restrict the xfine-vector to this level Epetra_Vector* xthis = coarseinterface_->restrict_fine_to_this(xfine); if (!xthis) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: ML_Epetra::Nox_CoarseProblem_Interface::restrict_fine_to_this returned NULL on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } Epetra_Vector* xc = new Epetra_Vector(graph_->RowMap(),false); // FIXME: after intesive testing, this test might be obsolet #if 0 bool samemap = xc->Map().PointSameAs(xthis->Map()); if (samemap) { #endif xc->Update(1.0,*xthis,0.0); #if 0 } else { cout << "**WRN** Maps are not equal in\n" << "**WRN** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; // import the xthis vector in the Map that ML produced for graph_ Epetra_Import* importer = new Epetra_Import(graph_->RowMap(),xthis->Map()); int ierr = xc->Import(*xthis,*importer,Insert); if (ierr) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: export from xthis to xc returned err=" << ierr <<"\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } if (importer) delete importer; importer = 0; } #endif if (xthis) delete xthis; xthis = 0; // create the coloring of the graph if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Entering Coloring on level " << level_ << "\n"; fflush(stdout); } double t0 = GetClock(); colorMap_ = ML_NOX::ML_Nox_collapsedcoloring(graph_,bsize_,isDiagonalOnly,ml_printlevel_); if (!colorMap_) colorMap_ = ML_NOX::ML_Nox_standardcoloring(graph_,isDiagonalOnly); colorMapIndex_ = new EpetraExt::CrsGraph_MapColoringIndex(*colorMap_); colorcolumns_ = &(*colorMapIndex_)(*graph_); double t1 = GetClock(); if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Proc " << comm_.MyPID() <<" Coloring time is " << (t1-t0) << " sec\n"; fflush(stdout); } // construct the FiniteDifferenceColoring-Matrix if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Entering Construction FD-Operator on level " << level_ << "\n"; fflush(stdout); } t0 = GetClock(); #if 1 // FD-operator with coloring FD_ = new NOX::EpetraNew::FiniteDifferenceColoring(*coarseinterface_, *xc, *graph_, *colorMap_, *colorcolumns_, true, isDiagonalOnly_, fd_beta_,fd_alpha_); #else // FD-operator without coloring FD_ = new NOX::EpetraNew::FiniteDifference(*coarseinterface_, *xc, *graph_, fd_beta_,fd_alpha_); #endif // set differencing method if (fd_centered_) FD_->setDifferenceMethod(NOX::EpetraNew::FiniteDifferenceColoring::Centered); bool err = FD_->computeJacobian(*xc); if (err==false) { cout << "**ERR**: ML_NOX::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: NOX::Epetra::FiniteDifferenceColoring returned an error on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } // print number of calls to the coarse interface if (ml_printlevel_>0 && comm_.MyPID()==0) cout << "matrixfreeML (level " << level_ << "): Calls to coarse-computeF in FD-Operator: " << coarseinterface_->numcallscomputeF() << "\n"; t1 = GetClock(); if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Proc " << comm_.MyPID() <<" colored Finite Differencing time is " << (t1-t0) << " sec\n"; fflush(stdout); } // get ref to computed Epetra_CrsMatrix A_ = dynamic_cast<Epetra_CrsMatrix*>(&(FD_->getUnderlyingMatrix())); // set counter for number of calls to the coarseinterface_->computeF back to zero coarseinterface_->resetnumcallscomputeF(); // tidy up if (xc) delete xc; xc = 0; return; }
/*----------------------------------------------------------------------* | recreate this level (public) m.gee 01/05| | this function assumes, that the graph of the fine level problem has | | not changed since call to the constructor and therefore | | the graph and it's coloring do not have to be recomputed | | IMPORTANT: | | No matter on which level we are here, the vector xfine is ALWAYS | | a fine grid vector here! | *----------------------------------------------------------------------*/ bool ML_NOX::ML_Nox_MatrixfreeLevel::recreateLevel(int level, int nlevel, int plevel, ML* ml, ML_Aggregate* ag, Epetra_CrsMatrix** P, ML_NOX::Ml_Nox_Fineinterface& interface, const Epetra_Comm& comm, const Epetra_Vector& xfine) { // make some tests if (level != level_) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::recreateLevel:\n" << "**ERR**: level_ " << level_ << " not equal level " << level << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } if (nlevel != nlevel_) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::recreateLevel:\n" << "**ERR**: nlevel_ " << nlevel_ << " not equal nlevel " << nlevel << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } // printlevel might have changed ml_printlevel_ = plevel; ml_ = ml; ag_ = ag; destroyP(); // safer to use the new Ps setP(NULL); // we need the graph of the operator on this level. On the fine grid we can just ask the // fineinterface for it, on the coarser levels it has to be extracted from the ML-hierachy bool same; if (level_==0) { const Epetra_CrsGraph* graph = interface.getGraph(); // check whether the old graph matches the new one same = compare_graphs(graph,graph_); destroyFD(); // we are here to recompute the FD-operator (this destroys graph_) graph_ = ML_NOX::deepcopy_graph(graph); } else { // Note that ML has no understanding of global indices, so it makes up new GIDs // (This also holds for the Prolongators P) Epetra_CrsMatrix* tmpMat = 0; int maxnnz = 0; double cputime = 0.0; ML_Operator2EpetraCrsMatrix(&(ml_->Amat[level_]), tmpMat, maxnnz, false, cputime); // get a view from the graph const Epetra_CrsGraph& graph = tmpMat->Graph(); // compare the graph to the existing one same = compare_graphs(&graph,graph_); destroyFD(); // we are here to recompute the FD-operator (this destroys graph_) double t0 = GetClock(); graph_ = ML_NOX::deepcopy_graph(&graph); // delete the copy of the Epetra_CrsMatrix if (tmpMat) delete tmpMat; tmpMat = 0; double t1 = GetClock(); if (ml_printlevel_ > 0 && 0 == comm_.MyPID()) cout << "matrixfreeML (level " << level_ << "): extraction/copy of Graph in " << cputime+t1-t0 << " sec\n" << " max-nonzeros in Graph: " << maxnnz << "\n"; } // recreate this levels coarse interface if (same) coarseinterface_->recreate(ml_printlevel_,P,&(graph_->RowMap())); else { delete coarseinterface_; coarseinterface_ = new ML_NOX::Nox_CoarseProblem_Interface(fineinterface_,level_,ml_printlevel_, P,&(graph_->RowMap()),nlevel_); } // restrict the xfine-vector to this level Epetra_Vector* xthis = coarseinterface_->restrict_fine_to_this(xfine); if (!xthis) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: ML_Epetra::Nox_CoarseProblem_Interface::restrict_fine_to_this returned NULL on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } Epetra_Vector* xc = new Epetra_Vector(graph_->RowMap(),false); // FIXME: after intesive testing, this test might be obsolet #if 0 bool samemap = xc->Map().PointSameAs(xthis->Map()); if (samemap) { #endif xc->Update(1.0,*xthis,0.0); #if 0 } else { cout << "**WRN** Maps are not equal in\n" << "**WRN** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; // import the xthis vector in the Map that ML produced for graph_ Epetra_Import* importer = new Epetra_Import(graph_->RowMap(),xthis->Map()); int ierr = xc->Import(*xthis,*importer,Insert); if (ierr) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: export from xthis to xc returned err=" << ierr <<"\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } if (importer) delete importer; importer = 0; } #endif if (xthis) delete xthis; xthis = 0; // create the coloring of the graph if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Entering Recoloring on level " << level_ << "\n"; fflush(stdout); } double t0 = GetClock(); if (!same) // te graph has obviously changed, so we need to recolor { if (colorMap_) delete colorMap_; colorMap_ = 0; if (colorMapIndex_) delete colorMapIndex_; colorMapIndex_ = 0; if (colorcolumns_) delete colorcolumns_; colorcolumns_ = 0; colorMap_ = ML_NOX::ML_Nox_collapsedcoloring(graph_,bsize_,isDiagonalOnly_,ml_printlevel_); if (!colorMap_) colorMap_ = ML_NOX::ML_Nox_standardcoloring(graph_,isDiagonalOnly_); colorMapIndex_ = new EpetraExt::CrsGraph_MapColoringIndex(*colorMap_); colorcolumns_ = &(*colorMapIndex_)(*graph_); } else if (ml_printlevel_>0 && comm_.MyPID()==0) cout << "matrixfreeML (level " << level_ << "): Reusing existing Coloring on level " << level_ << "\n"; double t1 = GetClock(); if (ml_printlevel_>5) { cout << "matrixfreeML (level " << level_ << "): Proc " << comm_.MyPID() <<" (Re)Coloring time is " << (t1-t0) << " sec\n"; fflush(stdout); } #if 0 // print the colorMap_ if (comm_.MyPID()==0) cout << "colorMap_\n"; cout << *colorMap_; for (int i=0; i<colorcolumns_->size(); i++) { if (comm_.MyPID()==0) cout << "the " << i << " th colorcolumn_ - vector\n"; cout << colorcolumns_->operator[](i); } #endif // construct the FiniteDifferenceColoring-Matrix if (ml_printlevel_>0 && comm_.MyPID()==0) { cout << "matrixfreeML (level " << level_ << "): Entering Construction FD-Operator on level " << level_ << "\n"; fflush(stdout); } t0 = GetClock(); #if 1 // FD-operator with coloring (see the #if 1 in ml_nox_matrixfreelevel.H as well!) FD_ = new NOX::EpetraNew::FiniteDifferenceColoring(*coarseinterface_, *xc, *graph_, *colorMap_, *colorcolumns_, true, isDiagonalOnly_, fd_beta_,fd_alpha_); #else // FD-operator without coloring FD_ = new NOX::EpetraNew::FiniteDifference(*coarseinterface_, *xc, *graph_, fd_beta_,fd_alpha_); #endif // set differencing method if (fd_centered_) { FD_->setDifferenceMethod(NOX::EpetraNew::FiniteDifferenceColoring::Centered); } bool err = FD_->computeJacobian(*xc); if (err==false) { cout << "**ERR**: ML_Epetra::ML_Nox_MatrixfreeLevel::ML_Nox_MatrixfreeLevel:\n" << "**ERR**: NOX::Epetra::FiniteDifferenceColoring returned an error on level " << level_ << "\n" << "**ERR**: file/line: " << __FILE__ << "/" << __LINE__ << "\n"; throw -1; } t1 = GetClock(); if (ml_printlevel_>5) cout << "matrixfreeML (level " << level_ << "): Proc " << comm_.MyPID() <<" Finite Differencing operator constr. in " << (t1-t0) << " sec\n"; // get ref to computed Epetra_CrsMatrix A_ = dynamic_cast<Epetra_CrsMatrix*>(&(FD_->getUnderlyingMatrix())); // print number of calls to the coarse interface if (ml_printlevel_>5 && comm_.MyPID()==0) cout << "matrixfreeML (level " << level_ << "): Calls to coarse-computeF in FD-Operator: " << coarseinterface_->numcallscomputeF() << "\n"; // set counter for number of calls to the coarseinterface_->computeF back to zero coarseinterface_->resetnumcallscomputeF(); // tidy up if (xc) delete xc; xc = 0; return true; }
void BiCGSTAB(Epetra_CrsMatrix &A, Epetra_Vector &x, Epetra_Vector &b, Ifpack_CrsRiluk *M, int Maxiter, double Tolerance, double *residual, bool verbose) { // Allocate vectors needed for iterations Epetra_Vector phat(x.Map()); phat.SetFlopCounter(x); Epetra_Vector p(x.Map()); p.SetFlopCounter(x); Epetra_Vector shat(x.Map()); shat.SetFlopCounter(x); Epetra_Vector s(x.Map()); s.SetFlopCounter(x); Epetra_Vector r(x.Map()); r.SetFlopCounter(x); Epetra_Vector rtilde(x.Map()); rtilde.Random(); rtilde.SetFlopCounter(x); Epetra_Vector v(x.Map()); v.SetFlopCounter(x); A.Multiply(false, x, r); // r = A*x r.Update(1.0, b, -1.0); // r = b - A*x double r_norm, b_norm, scaled_r_norm, rhon, rhonm1 = 1.0; double alpha = 1.0, omega = 1.0, sigma; double omega_num, omega_den; r.Norm2(&r_norm); b.Norm2(&b_norm); scaled_r_norm = r_norm/b_norm; r.Dot(rtilde,&rhon); if (verbose) cout << "Initial residual = " << r_norm << " Scaled residual = " << scaled_r_norm << endl; for (int i=0; i<Maxiter; i++) { // Main iteration loop double beta = (rhon/rhonm1) * (alpha/omega); rhonm1 = rhon; /* p = r + beta*(p - omega*v) */ /* phat = M^-1 p */ /* v = A phat */ double dtemp = - beta*omega; p.Update(1.0, r, dtemp, v, beta); if (M==0) phat.Scale(1.0, p); else M->Solve(false, p, phat); A.Multiply(false, phat, v); rtilde.Dot(v,&sigma); alpha = rhon/sigma; /* s = r - alpha*v */ /* shat = M^-1 s */ /* r = A shat (r is a tmp here for t ) */ s.Update(-alpha, v, 1.0, r, 0.0); if (M==0) shat.Scale(1.0, s); else M->Solve(false, s, shat); A.Multiply(false, shat, r); r.Dot(s, &omega_num); r.Dot(r, &omega_den); omega = omega_num / omega_den; /* x = x + alpha*phat + omega*shat */ /* r = s - omega*r */ x.Update(alpha, phat, omega, shat, 1.0); r.Update(1.0, s, -omega); r.Norm2(&r_norm); scaled_r_norm = r_norm/b_norm; r.Dot(rtilde,&rhon); if (verbose) cout << "Iter "<< i << " residual = " << r_norm << " Scaled residual = " << scaled_r_norm << endl; if (scaled_r_norm < Tolerance) break; } return; }
int TestOneMatrix( std::string HBname, std::string MMname, std::string TRIname, Epetra_Comm &Comm, bool verbose ) { if ( Comm.MyPID() != 0 ) verbose = false ; Epetra_Map * readMap = 0; Epetra_CrsMatrix * HbA = 0; Epetra_Vector * Hbx = 0; Epetra_Vector * Hbb = 0; Epetra_Vector * Hbxexact = 0; Epetra_CrsMatrix * TriplesA = 0; Epetra_Vector * Triplesx = 0; Epetra_Vector * Triplesb = 0; Epetra_Vector * Triplesxexact = 0; Epetra_CrsMatrix * MatrixMarketA = 0; Epetra_Vector * MatrixMarketx = 0; Epetra_Vector * MatrixMarketb = 0; Epetra_Vector * MatrixMarketxexact = 0; int TRI_Size = TRIname.size() ; std::string LastFiveBytes = TRIname.substr( EPETRA_MAX(0,TRI_Size-5), TRI_Size ); if ( LastFiveBytes == ".TimD" ) { // Call routine to read in a file with a Tim Davis header and zero-based indexing EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra64( &TRIname[0], false, Comm, readMap, TriplesA, Triplesx, Triplesb, Triplesxexact, false, true, true ) ); delete readMap; } else { if ( LastFiveBytes == ".triU" ) { // Call routine to read in unsymmetric Triplet matrix EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra64( &TRIname[0], false, Comm, readMap, TriplesA, Triplesx, Triplesb, Triplesxexact, false, false ) ); delete readMap; } else { if ( LastFiveBytes == ".triS" ) { // Call routine to read in symmetric Triplet matrix EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra64( &TRIname[0], true, Comm, readMap, TriplesA, Triplesx, Triplesb, Triplesxexact, false, false ) ); delete readMap; } else { assert( false ) ; } } } EPETRA_CHK_ERR( Trilinos_Util_ReadMatrixMarket2Epetra64( &MMname[0], Comm, readMap, MatrixMarketA, MatrixMarketx, MatrixMarketb, MatrixMarketxexact) ); delete readMap; // Call routine to read in HB problem Trilinos_Util_ReadHb2Epetra64( &HBname[0], Comm, readMap, HbA, Hbx, Hbb, Hbxexact) ; #if 0 std::cout << " HbA " ; HbA->Print( std::cout ) ; std::cout << std::endl ; std::cout << " MatrixMarketA " ; MatrixMarketA->Print( std::cout ) ; std::cout << std::endl ; std::cout << " TriplesA " ; TriplesA->Print( std::cout ) ; std::cout << std::endl ; #endif int TripleErr = 0 ; int MMerr = 0 ; for ( int i = 0 ; i < 10 ; i++ ) { double resid_Hb_Triples; double resid_Hb_Matrix_Market; double norm_A ; Hbx->Random(); // // Set the output vectors to different values: // Triplesb->PutScalar(1.1); Hbb->PutScalar(1.2); MatrixMarketb->PutScalar(1.3); HbA->Multiply( false, *Hbx, *Hbb ); norm_A = HbA->NormOne( ) ; TriplesA->Multiply( false, *Hbx, *Triplesb ); Triplesb->Update( 1.0, *Hbb, -1.0 ) ; MatrixMarketA->Multiply( false, *Hbx, *MatrixMarketb ); MatrixMarketb->Update( 1.0, *Hbb, -1.0 ) ; Triplesb->Norm1( &resid_Hb_Triples ) ; MatrixMarketb->Norm1( &resid_Hb_Matrix_Market ) ; TripleErr += ( resid_Hb_Triples > 1e-11 * norm_A ) ; MMerr += ( resid_Hb_Matrix_Market > 1e-11 * norm_A ) ; if ( verbose && resid_Hb_Triples > 1e-11 * norm_A ) std::cout << " resid_Hb_Triples = " << resid_Hb_Triples << " norm_A = " << norm_A << std::endl ; if ( verbose && resid_Hb_Matrix_Market > 1e-11 * norm_A ) std::cout << " resid_Hb_Matrix_Market = " << resid_Hb_Matrix_Market << " norm_A = " << norm_A << std::endl ; } if ( verbose ) { if ( TripleErr ) std::cout << " Error in reading " << HBname << " or " << TRIname << std::endl ; if ( MMerr ) std::cout << " Error in reading " << HBname << " or " << MMname << std::endl ; } delete HbA; delete Hbx; delete Hbb; delete Hbxexact; delete TriplesA; delete Triplesx; delete Triplesb; delete Triplesxexact; delete MatrixMarketA; delete MatrixMarketx; delete MatrixMarketb; delete MatrixMarketxexact; delete readMap; return TripleErr+MMerr ; }
//! Update vector static void update(Epetra_Vector& vec, double a, const Epetra_Vector& x) { vec.Update(a,x,1.0); }
// ================================================ ====== ==== ==== == = // the tentative null space is in input because the user // has to remember to allocate and fill it, and then to delete // it after calling this method. int ML_Epetra::MultiLevelPreconditioner:: ComputeAdaptivePreconditioner(int TentativeNullSpaceSize, double* TentativeNullSpace) { if ((TentativeNullSpaceSize == 0) || (TentativeNullSpace == 0)) ML_CHK_ERR(-1); // ================================== // // get parameters from the input list // // ================================== // // maximum number of relaxation sweeps int MaxSweeps = List_.get("adaptive: max sweeps", 10); // number of std::vector to be added to the tentative null space int NumAdaptiveVectors = List_.get("adaptive: num vectors", 1); if (verbose_) { std::cout << PrintMsg_ << "*** Adaptive Smoother Aggregation setup ***" << std::endl; std::cout << PrintMsg_ << " Maximum relaxation sweeps = " << MaxSweeps << std::endl; std::cout << PrintMsg_ << " Additional vectors to compute = " << NumAdaptiveVectors << std::endl; } // ==================================================== // // compute the preconditioner, set null space from user // // (who will have to delete std::vector TentativeNullSpace) // // ==================================================== // double* NewNullSpace = 0; double* OldNullSpace = TentativeNullSpace; int OldNullSpaceSize = TentativeNullSpaceSize; // need some work otherwise matvec() with Epetra_Vbr fails. // Also, don't differentiate between range and domain here // as ML will not work if range != domain const Epetra_VbrMatrix* VbrA = NULL; VbrA = dynamic_cast<const Epetra_VbrMatrix*>(RowMatrix_); Epetra_Vector* LHS = 0; Epetra_Vector* RHS = 0; if (VbrA != 0) { LHS = new Epetra_Vector(VbrA->DomainMap()); RHS = new Epetra_Vector(VbrA->DomainMap()); } else { LHS = new Epetra_Vector(RowMatrix_->OperatorDomainMap()); RHS = new Epetra_Vector(RowMatrix_->OperatorDomainMap()); } // destroy what we may already have if (IsComputePreconditionerOK_ == true) { DestroyPreconditioner(); } // build the preconditioner for the first time List_.set("null space: type", "pre-computed"); List_.set("null space: dimension", OldNullSpaceSize); List_.set("null space: vectors", OldNullSpace); ComputePreconditioner(); // ====================== // // add one std::vector at time // // ====================== // for (int istep = 0 ; istep < NumAdaptiveVectors ; ++istep) { if (verbose_) { std::cout << PrintMsg_ << "\tAdaptation step " << istep << std::endl; std::cout << PrintMsg_ << "\t---------------" << std::endl; } // ==================== // // look for "bad" modes // // ==================== // // note: should an error occur, ML_CHK_ERR will return, // and LHS and RHS will *not* be delete'd (--> memory leak). // Anyway, this means that something wrong happened in the code // and should be fixed by the user. LHS->Random(); double Norm2; for (int i = 0 ; i < MaxSweeps ; ++i) { // RHS = (I - ML^{-1} A) LHS ML_CHK_ERR(RowMatrix_->Multiply(false,*LHS,*RHS)); // FIXME: can do something slightly better here ML_CHK_ERR(ApplyInverse(*RHS,*RHS)); ML_CHK_ERR(LHS->Update(-1.0,*RHS,1.0)); LHS->Norm2(&Norm2); if (verbose_) { std::cout << PrintMsg_ << "\titer " << i << ", ||x||_2 = "; std::cout << Norm2 << std::endl; } } // scaling vectors double NormInf; LHS->NormInf(&NormInf); LHS->Scale(1.0 / NormInf); // ========================================================= // // copy tentative and computed null space into NewNullSpace, // // which now becomes the standard null space // // ========================================================= // int NewNullSpaceSize = OldNullSpaceSize + 1; NewNullSpace = new double[NumMyRows() * NewNullSpaceSize]; assert (NewNullSpace != 0); int itmp = OldNullSpaceSize * NumMyRows(); for (int i = 0 ; i < itmp ; ++i) { NewNullSpace[i] = OldNullSpace[i]; } for (int j = 0 ; j < NumMyRows() ; ++j) { NewNullSpace[itmp + j] = (*LHS)[j]; } // =============== // // visualize modes // // =============== // if (List_.get("adaptive: visualize", false)) { double* x_coord = List_.get("viz: x-coordinates", (double*)0); double* y_coord = List_.get("viz: y-coordinates", (double*)0); double* z_coord = List_.get("viz: z-coordinates", (double*)0); assert (x_coord != 0); std::vector<double> plot_me(NumMyRows()/NumPDEEqns_); ML_Aggregate_Viz_Stats info; info.Amatrix = &(ml_->Amat[LevelID_[0]]); info.x = x_coord; info.y = y_coord; info.z = z_coord; info.Nlocal = NumMyRows() / NumPDEEqns_; info.Naggregates = 1; ML_Operator_AmalgamateAndDropWeak(&(ml_->Amat[LevelID_[0]]), NumPDEEqns_, 0.0); for (int ieqn = 0 ; ieqn < NumPDEEqns_ ; ++ieqn) { for (int j = 0 ; j < NumMyRows() ; j+=NumPDEEqns_) { plot_me[j / NumPDEEqns_] = (*LHS)[j + ieqn]; } char FileName[80]; sprintf(FileName,"nullspace-mode%d-eq%d.xyz", istep, ieqn); if (verbose_) std::cout << PrintMsg_ << "writing file " << FileName << "..." << std::endl; ML_Aggregate_VisualizeXYZ(info,FileName, ml_->comm,&plot_me[0]); } ML_Operator_UnAmalgamateAndDropWeak(&(ml_->Amat[LevelID_[0]]), NumPDEEqns_, 0.0); } // Destroy the old preconditioner DestroyPreconditioner(); // ==================================================== // // build the new preconditioner with the new null space // // ==================================================== // List_.set("null space: type", "pre-computed"); List_.set("null space: dimension", NewNullSpaceSize); List_.set("null space: vectors", NewNullSpace); ML_CHK_ERR(ComputePreconditioner()); if (istep && (istep != NumAdaptiveVectors)) delete OldNullSpace; OldNullSpace = NewNullSpace; OldNullSpaceSize = NewNullSpaceSize; } // keep trace of this pointer, it will be delete'd later NullSpaceToFree_ = NewNullSpace; delete LHS; delete RHS; return(0); }
void exampleRoutine (const Epetra_Comm& comm, std::ostream& out) { using std::endl; // Print out the Epetra software version. if (comm.MyPID () == 0) { out << Epetra_Version () << endl << endl; } // The type of global indices. You could just set this to int, // but we want the example to work for Epetra64 as well. #ifdef EPETRA_NO_32BIT_GLOBAL_INDICES // Epetra was compiled only with 64-bit global index support, so use // 64-bit global indices. typedef long long global_ordinal_type; #else // Epetra was compiled with 32-bit global index support. If // EPETRA_NO_64BIT_GLOBAL_INDICES is defined, it does not also // support 64-bit indices. typedef int global_ordinal_type; #endif // EPETRA_NO_32BIT_GLOBAL_INDICES ////////////////////////////////////////////////////////////////////// // Create some Epetra_Map objects ////////////////////////////////////////////////////////////////////// // // Epetra has local and global Maps. Local maps describe objects // that are replicated over all participating MPI processes. Global // maps describe distributed objects. You can do imports and // exports between local and global maps; this is how you would turn // locally replicated objects into distributed objects and vice // versa. // // The total (global, i.e., over all MPI processes) number of // entries in the Map. This has the same type as that of global // indices, so it can represent very large values if Epetra was // built with 64-bit global index support. // // For this example, we scale the global number of entries in the // Map with the number of MPI processes. That way, you can run this // example with any number of MPI processes and every process will // still have a positive number of entries. const global_ordinal_type numGlobalEntries = comm.NumProc () * 5; // Tpetra can index the entries of a Map starting with 0 (C style), // 1 (Fortran style), or any base you want. 1-based indexing is // handy when interfacing with Fortran. We choose 0-based indexing // here. This also has the same type as that of global indices. const global_ordinal_type indexBase = 0; // Construct a Map that puts the same number of equations on each // (MPI) process. The Epetra_Comm is passed in by value, but that's // OK, because Epetra_Comm has shallow copy semantics. (Its copy // constructor and assignment operator do not call MPI_Comm_dup; // they just pass along the MPI_Comm.) Epetra_Map contigMap (numGlobalEntries, indexBase, comm); // contigMap is contiguous by construction. if (! contigMap.LinearMap ()) { throw std::logic_error ("The supposedly contiguous Map isn't contiguous."); } // Let's create a second Map. It will have the same number of // global entries per process, but will distribute them differently, // in round-robin (1-D cyclic) fashion instead of contiguously. // We'll use the version of the Map constructor that takes, on each // MPI process, a list of the global indices in the Map belonging to // that process. You can use this constructor to construct an // overlapping (also called "not 1-to-1") Map, in which one or more // entries are owned by multiple processes. We don't do that here; // we make a nonoverlapping (also called "1-to-1") Map. const int numGblIndsPerProc = 5; global_ordinal_type* gblIndList = new global_ordinal_type [numGblIndsPerProc]; const int numProcs = comm.NumProc (); const int myRank = comm.MyPID (); for (int k = 0; k < numGblIndsPerProc; ++k) { gblIndList[k] = myRank + k*numProcs; } Epetra_Map cyclicMap (numGlobalEntries, numGblIndsPerProc, gblIndList, indexBase, comm); // The above constructor makes a deep copy of the input index list, // so it's safe to deallocate that list after this constructor // completes. if (gblIndList != NULL) { delete [] gblIndList; gblIndList = NULL; } // If there's more than one MPI process in the communicator, // then cyclicMap is definitely NOT contiguous. if (comm.NumProc () > 1 && cyclicMap.LinearMap ()) { throw std::logic_error ("The cyclic Map claims to be contiguous."); } // contigMap and cyclicMap should always be compatible. However, if // the communicator contains more than 1 process, then contigMap and // cyclicMap are NOT the same. // if (! contigMap.isCompatible (*cyclicMap)) { // throw std::logic_error ("contigMap should be compatible with cyclicMap, " // "but it's not."); // } if (comm.NumProc () > 1 && contigMap.SameAs (cyclicMap)) { throw std::logic_error ("contigMap should not be the same as cyclicMap."); } ////////////////////////////////////////////////////////////////////// // We have maps now, so we can create vectors. ////////////////////////////////////////////////////////////////////// // Create an Epetra_Vector with the contiguous Map we created above. // This version of the constructor will fill the vector with zeros. // The Vector constructor takes a Map by value, but that's OK, // because Epetra_Map has shallow copy semantics. It uses reference // counting internally to avoid copying data unnecessarily. Epetra_Vector x (contigMap); // The copy constructor performs a deep copy. // x and y have the same Map. Epetra_Vector y (x); // Create a Vector with the 1-D cyclic Map. Calling the constructor // with false for the second argument leaves the data uninitialized, // so that you can fill it later without paying the cost of // initially filling it with zeros. Epetra_Vector z (cyclicMap, false); // Set the entries of z to (pseudo)random numbers. Please don't // consider this a good parallel pseudorandom number generator. (void) z.Random (); // Set the entries of x to all ones. (void) x.PutScalar (1.0); // Define some constants for use below. const double alpha = 3.14159; const double beta = 2.71828; const double gamma = -10.0; // x = beta*x + alpha*z // // This is a legal operation! Even though the Maps of x and z are // not the same, their Maps are compatible. Whether it makes sense // or not depends on your application. (void) x.Update (alpha, z, beta); (void) y.PutScalar (42.0); // Set all entries of y to 42.0 // y = gamma*y + alpha*x + beta*z y.Update (alpha, x, beta, z, gamma); // Compute the 2-norm of y. // // The norm may have a different type than scalar_type. // For example, if scalar_type is complex, then the norm is real. // The ScalarTraits "traits class" gives us the type of the norm. double theNorm = 0.0; (void) y.Norm2 (&theNorm); // Print the norm of y on Proc 0. out << "Norm of y: " << theNorm << endl; }
int Amesos_TestSolver( Epetra_Comm &Comm, char *matrix_file, SparseSolverType SparseSolver, bool transpose, int special, AMESOS_MatrixType matrix_type ) { Epetra_Map * readMap; Epetra_CrsMatrix * readA; Epetra_Vector * readx; Epetra_Vector * readb; Epetra_Vector * readxexact; std::string FileName = matrix_file ; int FN_Size = FileName.size() ; std::string LastFiveBytes = FileName.substr( EPETRA_MAX(0,FN_Size-5), FN_Size ); std::string LastFourBytes = FileName.substr( EPETRA_MAX(0,FN_Size-4), FN_Size ); bool NonContiguousMap = false; if ( LastFiveBytes == ".triU" ) { // Call routine to read in unsymmetric Triplet matrix NonContiguousMap = true; EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra( matrix_file, false, Comm, readMap, readA, readx, readb, readxexact, NonContiguousMap ) ); } else { if ( LastFiveBytes == ".triS" ) { NonContiguousMap = true; // Call routine to read in symmetric Triplet matrix EPETRA_CHK_ERR( Trilinos_Util_ReadTriples2Epetra( matrix_file, true, Comm, readMap, readA, readx, readb, readxexact, NonContiguousMap ) ); } else { if ( LastFourBytes == ".mtx" ) { EPETRA_CHK_ERR( Trilinos_Util_ReadMatrixMarket2Epetra( matrix_file, Comm, readMap, readA, readx, readb, readxexact) ); } else { // Call routine to read in HB problem Trilinos_Util_ReadHb2Epetra( matrix_file, Comm, readMap, readA, readx, readb, readxexact) ; } } } Epetra_CrsMatrix transposeA(Copy, *readMap, 0); Epetra_CrsMatrix *serialA ; if ( transpose ) { assert( CrsMatrixTranspose( readA, &transposeA ) == 0 ); serialA = &transposeA ; } else { serialA = readA ; } Epetra_RowMatrix * passA = 0; Epetra_Vector * passx = 0; Epetra_Vector * passb = 0; Epetra_Vector * passxexact = 0; Epetra_Vector * passresid = 0; Epetra_Vector * passtmp = 0; // Create uniform distributed map Epetra_Map map(readMap->NumGlobalElements(), 0, Comm); Epetra_Map* map_; if( NonContiguousMap ) { // // map gives us NumMyElements and MyFirstElement; // int NumGlobalElements = readMap->NumGlobalElements(); int NumMyElements = map.NumMyElements(); int MyFirstElement = map.MinMyGID(); std::vector<int> MapMap_( NumGlobalElements ); readMap->MyGlobalElements( &MapMap_[0] ) ; Comm.Broadcast( &MapMap_[0], NumGlobalElements, 0 ) ; map_ = new Epetra_Map( NumGlobalElements, NumMyElements, &MapMap_[MyFirstElement], 0, Comm); } else { map_ = new Epetra_Map( map ) ; } Epetra_CrsMatrix A(Copy, *map_, 0); const Epetra_Map &OriginalMap = serialA->RowMatrixRowMap() ; assert( OriginalMap.SameAs(*readMap) ); Epetra_Export exporter(OriginalMap, *map_); Epetra_Export exporter2(OriginalMap, *map_); Epetra_Export MatrixExporter(OriginalMap, *map_); Epetra_CrsMatrix AwithDiag(Copy, *map_, 0); Epetra_Vector x(*map_); Epetra_Vector b(*map_); Epetra_Vector xexact(*map_); Epetra_Vector resid(*map_); Epetra_Vector readresid(*readMap); Epetra_Vector tmp(*map_); Epetra_Vector readtmp(*readMap); // Epetra_Vector xcomp(*map_); // X as computed by the solver bool distribute_matrix = ( matrix_type == AMESOS_Distributed ) ; if ( distribute_matrix ) { // Create Exporter to distribute read-in matrix and vectors // // Initialize x, b and xexact to the values read in from the file // x.Export(*readx, exporter, Add); b.Export(*readb, exporter, Add); xexact.Export(*readxexact, exporter, Add); Comm.Barrier(); A.Export(*serialA, exporter, Add); assert(A.FillComplete()==0); Comm.Barrier(); passA = &A; passx = &x; passb = &b; passxexact = &xexact; passresid = &resid; passtmp = &tmp; } else { passA = serialA; passx = readx; passb = readb; passxexact = readxexact; passresid = &readresid; passtmp = &readtmp; } Epetra_MultiVector CopyB( *passb ) ; double Anorm = passA->NormInf() ; SparseDirectTimingVars::SS_Result.Set_Anorm(Anorm) ; Epetra_LinearProblem Problem( (Epetra_RowMatrix *) passA, (Epetra_MultiVector *) passx, (Epetra_MultiVector *) passb ); for ( int i = 0; i < 1+special ; i++ ) { Epetra_Time TotalTime( Comm ) ; if ( false ) { // TEST_UMFPACK is never set by configure #ifdef HAVE_AMESOS_SUPERLUDIST } else if ( SparseSolver == SUPERLUDIST ) { Teuchos::ParameterList ParamList ; ParamList.set( "MaxProcs", -3 ); Amesos_Superludist A_Superludist( Problem ) ; //ParamList.set( "Redistribute", true ); //ParamList.set( "AddZeroToDiag", true ); Teuchos::ParameterList& SuperludistParams = ParamList.sublist("Superludist") ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_Superludist.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_Superludist.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_Superludist.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_Superludist.NumericFactorization( ) ); EPETRA_CHK_ERR( A_Superludist.Solve( ) ); #endif #ifdef HAVE_AMESOS_DSCPACK } else if ( SparseSolver == DSCPACK ) { Teuchos::ParameterList ParamList ; ParamList.set( "MaxProcs", -3 ); Amesos_Dscpack A_dscpack( Problem ) ; EPETRA_CHK_ERR( A_dscpack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_dscpack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_dscpack.NumericFactorization( ) ); EPETRA_CHK_ERR( A_dscpack.Solve( ) ); #endif #ifdef HAVE_AMESOS_SCALAPACK } else if ( SparseSolver == SCALAPACK ) { Teuchos::ParameterList ParamList ; Amesos_Scalapack A_scalapack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_scalapack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_scalapack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_scalapack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_scalapack.NumericFactorization( ) ); EPETRA_CHK_ERR( A_scalapack.Solve( ) ); #endif #ifdef HAVE_AMESOS_TAUCS } else if ( SparseSolver == TAUCS ) { Teuchos::ParameterList ParamList ; Amesos_Taucs A_taucs( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_taucs.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_taucs.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_taucs.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_taucs.NumericFactorization( ) ); EPETRA_CHK_ERR( A_taucs.Solve( ) ); #endif #ifdef HAVE_AMESOS_PARDISO } else if ( SparseSolver == PARDISO ) { Teuchos::ParameterList ParamList ; Amesos_Pardiso A_pardiso( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_pardiso.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_pardiso.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_pardiso.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_pardiso.NumericFactorization( ) ); EPETRA_CHK_ERR( A_pardiso.Solve( ) ); #endif #ifdef HAVE_AMESOS_PARAKLETE } else if ( SparseSolver == PARAKLETE ) { Teuchos::ParameterList ParamList ; Amesos_Paraklete A_paraklete( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_paraklete.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_paraklete.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_paraklete.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_paraklete.NumericFactorization( ) ); EPETRA_CHK_ERR( A_paraklete.Solve( ) ); #endif #ifdef HAVE_AMESOS_MUMPS } else if ( SparseSolver == MUMPS ) { Teuchos::ParameterList ParamList ; Amesos_Mumps A_mumps( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_mumps.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_mumps.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_mumps.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_mumps.NumericFactorization( ) ); EPETRA_CHK_ERR( A_mumps.Solve( ) ); #endif #ifdef HAVE_AMESOS_SUPERLU } else if ( SparseSolver == SUPERLU ) { Teuchos::ParameterList ParamList ; Amesos_Superlu A_superlu( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_superlu.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_superlu.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_superlu.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_superlu.NumericFactorization( ) ); EPETRA_CHK_ERR( A_superlu.Solve( ) ); #endif #ifdef HAVE_AMESOS_LAPACK } else if ( SparseSolver == LAPACK ) { Teuchos::ParameterList ParamList ; Amesos_Lapack A_lapack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_lapack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_lapack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_lapack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_lapack.NumericFactorization( ) ); EPETRA_CHK_ERR( A_lapack.Solve( ) ); #endif #ifdef HAVE_AMESOS_UMFPACK } else if ( SparseSolver == UMFPACK ) { Teuchos::ParameterList ParamList ; Amesos_Umfpack A_umfpack( Problem ) ; ParamList.set( "MaxProcs", -3 ); EPETRA_CHK_ERR( A_umfpack.SetParameters( ParamList ) ); EPETRA_CHK_ERR( A_umfpack.SetUseTranspose( transpose ) ); EPETRA_CHK_ERR( A_umfpack.SymbolicFactorization( ) ); EPETRA_CHK_ERR( A_umfpack.NumericFactorization( ) ); EPETRA_CHK_ERR( A_umfpack.Solve( ) ); #endif #ifdef HAVE_AMESOS_KLU } else if ( SparseSolver == KLU ) { using namespace Teuchos; Amesos_Time AT; int setupTimePtr = -1, symTimePtr = -1, numTimePtr = -1, refacTimePtr = -1, solveTimePtr = -1; AT.CreateTimer(Comm, 2); AT.ResetTimer(0); Teuchos::ParameterList ParamList ; // ParamList.set("OutputLevel",2); Amesos_Klu A_klu( Problem ); ParamList.set( "MaxProcs", -3 ); ParamList.set( "TrustMe", false ); // ParamList.set( "Refactorize", true ); EPETRA_CHK_ERR( A_klu.SetParameters( ParamList ) ) ; EPETRA_CHK_ERR( A_klu.SetUseTranspose( transpose ) ); setupTimePtr = AT.AddTime("Setup", setupTimePtr, 0); EPETRA_CHK_ERR( A_klu.SymbolicFactorization( ) ); symTimePtr = AT.AddTime("Symbolic", symTimePtr, 0); EPETRA_CHK_ERR( A_klu.NumericFactorization( ) ); numTimePtr = AT.AddTime("Numeric", numTimePtr, 0); EPETRA_CHK_ERR( A_klu.NumericFactorization( ) ); refacTimePtr = AT.AddTime("Refactor", refacTimePtr, 0); // for ( int i=0; i<100000 ; i++ ) EPETRA_CHK_ERR( A_klu.Solve( ) ); solveTimePtr = AT.AddTime("Solve", solveTimePtr, 0); double SetupTime = AT.GetTime(setupTimePtr); double SymbolicTime = AT.GetTime(symTimePtr); double NumericTime = AT.GetTime(numTimePtr); double RefactorTime = AT.GetTime(refacTimePtr); double SolveTime = AT.GetTime(solveTimePtr); std::cout << __FILE__ << "::" << __LINE__ << " SetupTime = " << SetupTime << std::endl ; std::cout << __FILE__ << "::" << __LINE__ << " SymbolicTime = " << SymbolicTime - SetupTime << std::endl ; std::cout << __FILE__ << "::" << __LINE__ << " NumericTime = " << NumericTime - SymbolicTime<< std::endl ; std::cout << __FILE__ << "::" << __LINE__ << " RefactorTime = " << RefactorTime - NumericTime << std::endl ; std::cout << __FILE__ << "::" << __LINE__ << " SolveTime = " << SolveTime - RefactorTime << std::endl ; #endif } else { SparseDirectTimingVars::log_file << "Solver not implemented yet" << std::endl ; std::cerr << "\n\n#################### Requested solver not available on this platform ##################### ATS\n" << std::endl ; std::cout << " SparseSolver = " << SparseSolver << std::endl ; std::cerr << " SparseSolver = " << SparseSolver << std::endl ; } SparseDirectTimingVars::SS_Result.Set_Total_Time( TotalTime.ElapsedTime() ); } // end for (int i=0; i<special; i++ ) // // Compute the error = norm(xcomp - xexact ) // double error; passresid->Update(1.0, *passx, -1.0, *passxexact, 0.0); passresid->Norm2(&error); SparseDirectTimingVars::SS_Result.Set_Error(error) ; // passxexact->Norm2(&error ) ; // passx->Norm2(&error ) ; // // Compute the residual = norm(Ax - b) // double residual ; passA->Multiply( transpose, *passx, *passtmp); passresid->Update(1.0, *passtmp, -1.0, *passb, 0.0); // passresid->Update(1.0, *passtmp, -1.0, CopyB, 0.0); passresid->Norm2(&residual); SparseDirectTimingVars::SS_Result.Set_Residual(residual) ; double bnorm; passb->Norm2( &bnorm ) ; SparseDirectTimingVars::SS_Result.Set_Bnorm(bnorm) ; double xnorm; passx->Norm2( &xnorm ) ; SparseDirectTimingVars::SS_Result.Set_Xnorm(xnorm) ; delete readA; delete readx; delete readb; delete readxexact; delete readMap; delete map_; Comm.Barrier(); return 0; }