int InitMatValues( const Epetra_CrsMatrix& newA, Epetra_CrsMatrix* A ) { int numMyRows = newA.NumMyRows(); int maxNum = newA.MaxNumEntries(); int numIn; int *idx = 0; double *vals = 0; idx = new int[maxNum]; vals = new double[maxNum]; // For each row get the values and indices, and replace the values in A. for (int i=0; i<numMyRows; ++i) { // Get the values and indices from newA. EPETRA_CHK_ERR( newA.ExtractMyRowCopy(i, maxNum, numIn, vals, idx) ); // Replace the values in A EPETRA_CHK_ERR( A->ReplaceMyValues(i, numIn, vals, idx) ); } // Clean up. delete [] idx; delete [] vals; return 0; }
//EpetraCrsMatrix_To_TpetraCrsMatrix: copies Epetra_CrsMatrix to its analogous Tpetra_CrsMatrix Teuchos::RCP<Tpetra_CrsMatrix> Petra::EpetraCrsMatrix_To_TpetraCrsMatrix(const Epetra_CrsMatrix& epetraCrsMatrix_, const Teuchos::RCP<const Teuchos::Comm<int> >& commT_) { //get row map of Epetra::CrsMatrix & convert to Tpetra::Map auto tpetraRowMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.RowMap(), commT_); //get col map of Epetra::CrsMatrix & convert to Tpetra::Map auto tpetraColMap_ = EpetraMap_To_TpetraMap(epetraCrsMatrix_.ColMap(), commT_); //get CrsGraph of Epetra::CrsMatrix & convert to Tpetra::CrsGraph const Epetra_CrsGraph epetraCrsGraph_ = epetraCrsMatrix_.Graph(); std::size_t maxEntries = epetraCrsGraph_.GlobalMaxNumIndices(); Teuchos::RCP<Tpetra_CrsGraph> tpetraCrsGraph_ = Teuchos::rcp(new Tpetra_CrsGraph(tpetraRowMap_, tpetraColMap_, maxEntries)); for (LO i=0; i<epetraCrsGraph_.NumMyRows(); i++) { LO NumEntries; LO *Indices; epetraCrsGraph_.ExtractMyRowView(i, NumEntries, Indices); tpetraCrsGraph_->insertLocalIndices(i, NumEntries, Indices); } tpetraCrsGraph_->fillComplete(); //convert Epetra::CrsMatrix to Tpetra::CrsMatrix, after creating Tpetra::CrsMatrix based on above Tpetra::CrsGraph Teuchos::RCP<Tpetra_CrsMatrix> tpetraCrsMatrix_ = Teuchos::rcp(new Tpetra_CrsMatrix(tpetraCrsGraph_)); tpetraCrsMatrix_->setAllToScalar(0.0); for (LO i=0; i<epetraCrsMatrix_.NumMyRows(); i++) { LO NumEntries; LO *Indices; ST *Values; epetraCrsMatrix_.ExtractMyRowView(i, NumEntries, Values, Indices); tpetraCrsMatrix_->replaceLocalValues(i, NumEntries, Values, Indices); } tpetraCrsMatrix_->fillComplete(); return tpetraCrsMatrix_; }
//! Update matrix static void update(Epetra_CrsMatrix& mat, double a, const Epetra_CrsMatrix& x) { int num_col; for (int i=0; i<mat.NumMyRows(); i++) { mat.NumMyRowEntries(i, num_col); for (int j=0; j<num_col; j++) mat[i][j] += a*x[i][j]; } }
//============================================================================== Epetra_FastCrsMatrix::Epetra_FastCrsMatrix(const Epetra_CrsMatrix & Matrix, bool UseFloats) : CrsMatrix_(Matrix), Values_(0), NumMyRows_(Matrix.NumMyRows()), NumMyNonzeros(Matrix.NumMyNonzeros()), ImportVector_(0), ExportVector_(0), CV_(Copy) { if (!CrsMatrix_.Filled()) throw CrsMatrix_.ReportError("Input matrix must have called FillComplete()", -1); Allocate(UseFloats); }
/*----------------------------------------------------------------------* | m.gee 11/05| *----------------------------------------------------------------------*/ bool ML_NOX::Print_Epetra_CrsMatrix(Epetra_CrsMatrix& matrix) { for (int i=0; i<matrix.NumMyRows(); ++i) { printf("Lrow %5d: ",i); fflush(stdout); int numentries; int* indices; double* values; int err = matrix.ExtractMyRowView(i,numentries,values,indices); for (int j=0; j<numentries; ++j) printf("%5d %10.3e ",indices[j],values[j]); printf("\n"); fflush(stdout); } return true; }
//========================================================================= // NOTE: This method should be removed and replaced with calls to Epetra_Util_ExtractHbData() int Epetra_LinearProblemRedistor::ExtractHbData(int & M, int & N, int & nz, int * & ptr, int * & ind, double * & val, int & Nrhs, double * & rhs, int & ldrhs, double * & lhs, int & ldlhs) const { Epetra_CrsMatrix * RedistMatrix = dynamic_cast<Epetra_CrsMatrix *>(RedistProblem_->GetMatrix()); if (RedistMatrix==0) EPETRA_CHK_ERR(-1); // This matrix is zero or not an Epetra_CrsMatrix if (!RedistMatrix->IndicesAreContiguous()) { // Data must be contiguous for this to work EPETRA_CHK_ERR(-2); } M = RedistMatrix->NumMyRows(); N = RedistMatrix->NumMyCols(); nz = RedistMatrix->NumMyNonzeros(); val = (*RedistMatrix)[0]; // Dangerous, but cheap and effective way to access first element in const Epetra_CrsGraph & RedistGraph = RedistMatrix->Graph(); ind = RedistGraph[0]; // list of values and indices Epetra_MultiVector * LHS = RedistProblem_->GetLHS(); Epetra_MultiVector * RHS = RedistProblem_->GetRHS(); Nrhs = RHS->NumVectors(); if (Nrhs>1) { if (!RHS->ConstantStride()) {EPETRA_CHK_ERR(-3)}; // Must have strided vectors if (!LHS->ConstantStride()) {EPETRA_CHK_ERR(-4)}; // Must have strided vectors } ldrhs = RHS->Stride(); rhs = (*RHS)[0]; // Dangerous but effective (again) ldlhs = LHS->Stride(); lhs = (*LHS)[0]; // Finally build ptr vector if (ptr_==0) { ptr_ = new int[M+1]; ptr_[0] = 0; for (int i=0; i<M; i++) ptr_[i+1] = ptr_[i] + RedistGraph.NumMyIndices(i); } ptr = ptr_; return(0); }
void BroydenOperator::replaceBroydenMatrixValues( const Epetra_CrsMatrix & mat) { double * values ; int * indices ; int numEntries ; int ierr ; for( int row = 0; row < mat.NumMyRows(); ++row) { ierr = mat.ExtractMyRowView(row, numEntries, values, indices); ierr += crsMatrix->ReplaceGlobalValues(row, numEntries, values, indices); if( ierr ) { cout << "ERROR (" << ierr << ") : " << "NOX::Epetra::BroydenOperator::replaceBroydenMatrixValues(...)" << " - Extract or Replace values error for row --> " << row << endl; throw "NOX Broyden Operator Error"; } } }
// ====================================================================== inline void Apply_BCsToMatrixRowsAndColumns(const int *dirichletRows, int numBCRows,const Epetra_IntVector &dirichletColumns,const Epetra_CrsMatrix & Matrix){ /* This function zeros out rows & columns of Matrix. Comments: The graph of Matrix is unchanged. */ // Nuke the rows for(int i=0;i<numBCRows;i++){ int numEntries, *cols; double *vals; Matrix.ExtractMyRowView(dirichletRows[i],numEntries,vals,cols); for (int j=0; j<numEntries; j++) vals[j]=0.0; }/*end for*/ // Nuke the columns for (int i=0; i < Matrix.NumMyRows(); i++) { int numEntries; double *vals; int *cols; Matrix.ExtractMyRowView(i,numEntries,vals,cols); for (int j=0; j < numEntries; j++) { if (dirichletColumns[ cols[j] ] > 0) vals[j] = 0.0; }/*end for*/ }/*end for*/ }/* end Apply_BCsToMatrixColumns */
bool CrsMatrixInfo( const Epetra_CrsMatrix & A, ostream & os ) { int MyPID = A.Comm().MyPID(); // take care that matrix is already trasformed bool IndicesAreGlobal = A.IndicesAreGlobal(); if( IndicesAreGlobal == true ) { if( MyPID == 0 ) { os << "WARNING : matrix must be transformed to local\n"; os << " before calling CrsMatrixInfo\n"; os << " Now returning...\n"; } return false; } int NumGlobalRows = A.NumGlobalRows(); int NumGlobalNonzeros = A.NumGlobalNonzeros(); int NumGlobalCols = A.NumGlobalCols(); double NormInf = A.NormInf(); double NormOne = A.NormOne(); int NumGlobalDiagonals = A.NumGlobalDiagonals(); int GlobalMaxNumEntries = A.GlobalMaxNumEntries(); int IndexBase = A.IndexBase(); bool StorageOptimized = A.StorageOptimized(); bool LowerTriangular = A.LowerTriangular(); bool UpperTriangular = A.UpperTriangular(); bool NoDiagonal = A.NoDiagonal(); // these variables identifies quantities I have to compute, // since not provided by Epetra_CrsMatrix double MyFrobeniusNorm( 0.0 ), FrobeniusNorm( 0.0 ); double MyMinElement( DBL_MAX ), MinElement( DBL_MAX ); double MyMaxElement( DBL_MIN ), MaxElement( DBL_MIN ); double MyMinAbsElement( DBL_MAX ), MinAbsElement( DBL_MAX ); double MyMaxAbsElement( 0.0 ), MaxAbsElement( 0.0 ); int NumMyRows = A.NumMyRows(); int * NzPerRow = new int[NumMyRows]; int Row; // iterator on rows int Col; // iterator on cols int MaxNumEntries = A.MaxNumEntries(); double * Values = new double[MaxNumEntries]; int * Indices = new int[MaxNumEntries]; double Element, AbsElement; // generic nonzero element and its abs value int NumEntries; double * Diagonal = new double [NumMyRows]; // SumOffDiagonal is the sum of absolute values for off-diagonals double * SumOffDiagonal = new double [NumMyRows]; for( Row=0 ; Row<NumMyRows ; ++Row ) { SumOffDiagonal[Row] = 0.0; } int * IsDiagonallyDominant = new int [NumMyRows]; int GlobalRow; // cycle over all matrix elements for( Row=0 ; Row<NumMyRows ; ++Row ) { GlobalRow = A.GRID(Row); NzPerRow[Row] = A.NumMyEntries(Row); A.ExtractMyRowCopy(Row,NzPerRow[Row],NumEntries,Values,Indices); for( Col=0 ; Col<NumEntries ; ++Col ) { Element = Values[Col]; AbsElement = abs(Element); if( Element<MyMinElement ) MyMinElement = Element; if( Element>MyMaxElement ) MyMaxElement = Element; if( AbsElement<MyMinAbsElement ) MyMinAbsElement = AbsElement; if( AbsElement>MyMaxAbsElement ) MyMaxAbsElement = AbsElement; if( Indices[Col] == Row ) Diagonal[Row] = Element; else SumOffDiagonal[Row] += abs(Element); MyFrobeniusNorm += pow(Element,2); } } // analise storage per row int MyMinNzPerRow( NumMyRows ), MinNzPerRow( NumMyRows ); int MyMaxNzPerRow( 0 ), MaxNzPerRow( 0 ); for( Row=0 ; Row<NumMyRows ; ++Row ) { if( NzPerRow[Row]<MyMinNzPerRow ) MyMinNzPerRow=NzPerRow[Row]; if( NzPerRow[Row]>MyMaxNzPerRow ) MyMaxNzPerRow=NzPerRow[Row]; } // a test to see if matrix is diagonally-dominant int MyDiagonalDominance( 0 ), DiagonalDominance( 0 ); int MyWeakDiagonalDominance( 0 ), WeakDiagonalDominance( 0 ); for( Row=0 ; Row<NumMyRows ; ++Row ) { if( abs(Diagonal[Row])>SumOffDiagonal[Row] ) ++MyDiagonalDominance; else if( abs(Diagonal[Row])==SumOffDiagonal[Row] ) ++MyWeakDiagonalDominance; } // reduction operations A.Comm().SumAll(&MyFrobeniusNorm, &FrobeniusNorm, 1); A.Comm().MinAll(&MyMinElement, &MinElement, 1); A.Comm().MaxAll(&MyMaxElement, &MaxElement, 1); A.Comm().MinAll(&MyMinAbsElement, &MinAbsElement, 1); A.Comm().MaxAll(&MyMaxAbsElement, &MaxAbsElement, 1); A.Comm().MinAll(&MyMinNzPerRow, &MinNzPerRow, 1); A.Comm().MaxAll(&MyMaxNzPerRow, &MaxNzPerRow, 1); A.Comm().SumAll(&MyDiagonalDominance, &DiagonalDominance, 1); A.Comm().SumAll(&MyWeakDiagonalDominance, &WeakDiagonalDominance, 1); // free memory delete Values; delete Indices; delete Diagonal; delete SumOffDiagonal; delete IsDiagonallyDominant; delete NzPerRow; // simply no output for MyPID>0, only proc 0 write on os if( MyPID != 0 ) return true; os << "*** general Information about the matrix\n"; os << "Number of Global Rows = " << NumGlobalRows << endl; os << "Number of Global Cols = " << NumGlobalCols << endl; os << "is the matrix square = " << ((NumGlobalRows==NumGlobalCols)?"yes":"no") << endl; os << "||A||_\\infty = " << NormInf << endl; os << "||A||_1 = " << NormOne << endl; os << "||A||_F = " << sqrt(FrobeniusNorm) << endl; os << "Number of nonzero diagonal entries = " << NumGlobalDiagonals << "( " << 1.0* NumGlobalDiagonals/NumGlobalRows*100 << " %)\n"; os << "Nonzero per row : min = " << MinNzPerRow << " average = " << 1.0*NumGlobalNonzeros/NumGlobalRows << " max = " << MaxNzPerRow << endl; os << "Maximum number of nonzero elements/row = " << GlobalMaxNumEntries << endl; os << "min( a_{i,j} ) = " << MinElement << endl; os << "max( a_{i,j} ) = " << MaxElement << endl; os << "min( abs(a_{i,j}) ) = " << MinAbsElement << endl; os << "max( abs(a_{i,j}) ) = " << MaxAbsElement << endl; os << "Number of diagonal dominant rows = " << DiagonalDominance << " (" << 100.0*DiagonalDominance/NumGlobalRows << " % of total)\n"; os << "Number of weakly diagonal dominant rows = " << WeakDiagonalDominance << " (" << 100.0*WeakDiagonalDominance/NumGlobalRows << " % of total)\n"; os << "*** Information about the Trilinos storage\n"; os << "Base Index = " << IndexBase << endl; os << "is storage optimized = " << ((StorageOptimized==true)?"yes":"no") << endl; os << "are indices global = " << ((IndicesAreGlobal==true)?"yes":"no") << endl; os << "is matrix lower triangular = " << ((LowerTriangular==true)?"yes":"no") << endl; os << "is matrix upper triangular = " << ((UpperTriangular==true)?"yes":"no") << endl; os << "are there diagonal entries = " << ((NoDiagonal==false)?"yes":"no") << endl; return true; }
CrsMatrix_SolverMap::NewTypeRef CrsMatrix_SolverMap:: operator()( OriginalTypeRef orig ) { origObj_ = &orig; assert( !orig.IndicesAreGlobal() ); //test if matrix has missing local columns in its col std::map const Epetra_Map & RowMap = orig.RowMap(); const Epetra_Map & DomainMap = orig.DomainMap(); const Epetra_Map & ColMap = orig.ColMap(); const Epetra_Comm & Comm = RowMap.Comm(); int NumMyRows = RowMap.NumMyElements(); int NumCols = DomainMap.NumMyElements(); int Match = 0; for( int i = 0; i < NumCols; ++i ) if( DomainMap.GID(i) != ColMap.GID(i) ) { Match = 1; break; } int MatchAll = 0; Comm.SumAll( &Match, &MatchAll, 1 ); if( !MatchAll ) { newObj_ = origObj_; } else { //create ColMap with all local rows included std::vector<int> Cols(NumCols); //fill Cols list with GIDs of all local columns for( int i = 0; i < NumCols; ++i ) Cols[i] = DomainMap.GID(i); //now append to Cols any ghost column entries int NumMyCols = ColMap.NumMyElements(); for( int i = 0; i < NumMyCols; ++i ) if( !DomainMap.MyGID( ColMap.GID(i) ) ) Cols.push_back( ColMap.GID(i) ); int NewNumMyCols = Cols.size(); int NewNumGlobalCols; Comm.SumAll( &NewNumMyCols, &NewNumGlobalCols, 1 ); //create new column std::map NewColMap_ = new Epetra_Map( NewNumGlobalCols, NewNumMyCols,&Cols[0], DomainMap.IndexBase(), Comm ); //New Graph std::vector<int> NumIndicesPerRow( NumMyRows ); for( int i = 0; i < NumMyRows; ++i ) NumIndicesPerRow[i] = orig.NumMyEntries(i); NewGraph_ = new Epetra_CrsGraph( Copy, RowMap, *NewColMap_, &NumIndicesPerRow[0] ); int MaxNumEntries = orig.MaxNumEntries(); int NumEntries; std::vector<int> Indices( MaxNumEntries ); for( int i = 0; i < NumMyRows; ++i ) { int RowGID = RowMap.GID(i); orig.Graph().ExtractGlobalRowCopy( RowGID, MaxNumEntries, NumEntries, &Indices[0] ); NewGraph_->InsertGlobalIndices( RowGID, NumEntries, &Indices[0] ); } const Epetra_Map & RangeMap = orig.RangeMap(); NewGraph_->FillComplete(DomainMap,RangeMap); //intial construction of matrix Epetra_CrsMatrix * NewMatrix = new Epetra_CrsMatrix( View, *NewGraph_ ); //insert views of row values int * myIndices; double * myValues; int indicesCnt; int numMyRows = NewMatrix->NumMyRows(); for( int i = 0; i < numMyRows; ++i ) { orig.ExtractMyRowView( i, indicesCnt, myValues, myIndices ); NewGraph_->ExtractMyRowView( i, indicesCnt, myIndices ); NewMatrix->InsertMyValues( i, indicesCnt, myValues, myIndices ); } NewMatrix->FillComplete(DomainMap,RangeMap); newObj_ = NewMatrix; } return *newObj_; }
void Stokhos::AdaptivityManager:: sumInOperator(Epetra_CrsMatrix & A,const Stokhos::AdaptivityManager::Sparse3TensorHash & Cijk,int k,const Epetra_CrsMatrix & J_k) const { TEUCHOS_ASSERT(J_k.NumMyRows() == int(sg_basis_row_dof_.size())); TEUCHOS_ASSERT(J_k.NumMyCols() == int(sg_basis_col_dof_.size())); const Teuchos::Array<double> & normValues = sg_master_basis_->norm_squared(); // loop over deterministic rows for(int localM=0;localM<J_k.NumMyRows();localM++) { int m = J_k.GRID(localM); // grab row basis Teuchos::RCP<const Stokhos::ProductBasis<int,double> > rowStochBasis = sg_basis_row_dof_[localM]; // grab row from deterministic system int d_numEntries; int * d_Indices; double * d_Values; J_k.ExtractMyRowView(localM,d_numEntries,d_Values,d_Indices); // loop over stochastic degrees of freedom of this row for(int rb_i=0;rb_i<rowStochBasis->size();rb_i++) { int i = sg_master_basis_->index(rowStochBasis->term(rb_i)); double normValue = normValues[i]; // sg_master_basis->norm_squared(i); int sg_m = getGlobalRowId(localM,rb_i); // we wipe out old values, capacity should gurantee // we don't allocate more often than neccessary! std::vector<int> sg_indices; std::vector<double> sg_values; // sg_indices.resize(0); // sg_values.resize(0); // loop over each column for(int colInd=0;colInd<d_numEntries;colInd++) { int localN = d_Indices[colInd]; // grab local deterministic column id // grab row basis Teuchos::RCP<const Stokhos::ProductBasis<int,double> > colStochBasis = sg_basis_col_dof_[localN]; // build values array for(int cb_j=0;cb_j<colStochBasis->size();cb_j++) { int j = sg_master_basis_->index(colStochBasis->term(cb_j)); int sg_n = getGlobalColId(localN,cb_j); double cijk = Cijk.getValue(i,j,k); // no reason to work it in! if(cijk==0) continue; if(scaleOp_) cijk = cijk/normValue; sg_indices.push_back(sg_n); sg_values.push_back(cijk*d_Values[colInd]); } } // add in matrix values A.SumIntoGlobalValues(sg_m,sg_indices.size(),&sg_values[0],&sg_indices[0]); } } }
/*----------------------------------------------------------------------* | Create the spd system (public) mwgee 12/05| | Note that this is collective for ALL procs | *----------------------------------------------------------------------*/ Epetra_CrsMatrix* MOERTEL::Manager::MakeSPDProblem() { // time this process Epetra_Time time(Comm()); time.ResetStartTime(); // check whether all interfaces are complete and integrated std::map<int,Teuchos::RCP<MOERTEL::Interface> >::iterator curr; for (curr=interface_.begin(); curr != interface_.end(); ++curr) { if (curr->second->IsComplete() == false) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** interface " << curr->second->Id() << " is not Complete()\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } if (curr->second->IsIntegrated() == false) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** interface " << curr->second->Id() << " is not integrated yet\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } } // check whether we have a problemmap_ if (problemmap_==Teuchos::null) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** No problemmap_ set\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } // check whether we have a constraintsmap_ if (constraintsmap_==Teuchos::null) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** onstraintsmap is NULL\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } // check for saddlemap_ if (saddlemap_==Teuchos::null) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** saddlemap_==NULL\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } // check for inputmatrix if (inputmatrix_==Teuchos::null) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** No inputmatrix set\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } // check whether we have M and D matrices if (D_==Teuchos::null || M_==Teuchos::null) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** Matrix M or D is NULL\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; return NULL; } // we need a map from lagrange multiplier dofs to primal dofs on the same node std::vector<MOERTEL::Node*> nodes(0); std::map<int,int> lm_to_dof; for (curr=interface_.begin(); curr!=interface_.end(); ++curr) { Teuchos::RCP<MOERTEL::Interface> inter = curr->second; inter->GetNodeView(nodes); for (int i=0; i<(int)nodes.size(); ++i) { if (!nodes[i]->Nlmdof()) continue; const int* dof = nodes[i]->Dof(); const int* lmdof = nodes[i]->LMDof(); for (int j=0; j<nodes[i]->Nlmdof(); ++j) { //cout << "j " << j << " maps lmdof " << lmdof[j] << " to dof " << dof[j] << endl; lm_to_dof[lmdof[j]] = dof[j]; } } } lm_to_dof_ = Teuchos::rcp(new std::map<int,int>(lm_to_dof)); // this is a very useful map for the moertel_ml_preconditioner /* _ _ | | | Arr Arn Mr | S = | | | Anr Ann D | | | MrT D 0 | |_ _ | _ _ | | | Arr Arn | A = | | | Anr Ann | |_ _| 1) Ann is square and we need it's Range/DomainMap annmap _ _ WT = |_ 0 Dinv _| 2) Build WT (has rowmap/rangemap annmap and domainmap problemmap_) _ _ | | | Mr | B = | | | D | |_ _| 3) Build B (has rowmap/rangemap problemmap_ and domainmap annmap) 4) Build I, the identity matrix with maps problemmap_,problemmap_); After constructing WT ,B and I we can start building Atilde (spdmatrix_) Atilde = A + ( B WT - I) A W B^T + B WT A (W B^T - I) 5) Build BWT = B * WT 6) Build BWTmI = BWT - I 7) Build BWTmIAWBT = BWTmI * A * W * B^T 8) Allocate spdmatrix_ = A + BWTmIAWBT 9) Build WBTmI = WT^T * B^T - I 10) Build BWTAWBTmI = BWT * A * WBTmI and add to spdmatrix_ Call FillComplete on spdmatrix_ 11) Build ImBWT = I - BWT and store it */ int err=0; //-------------------------------------------------------------------------- // 1) create the rangemap of Ann std::vector<int> myanngids(problemmap_->NumMyElements()); int count=0; std::map<int,int>::iterator intintcurr; for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr) { if (problemmap_->MyGID(intintcurr->second)==false) continue; if ((int)myanngids.size()<=count) myanngids.resize(myanngids.size()+50); myanngids[count] = intintcurr->second; ++count; } myanngids.resize(count); int numglobalelements; Comm().SumAll(&count,&numglobalelements,1); Epetra_Map* annmap = new Epetra_Map(numglobalelements,count,&myanngids[0],0,Comm()); annmap_ = Teuchos::rcp(annmap); myanngids.clear(); #if 0 //-------------------------------------------------------------------------- // 1.5) split matrix into blocks Arr Arn Anr Ann Teuchos::RCP<Epetra_Map> A11row = Teuchos::null; Teuchos::RCP<Epetra_Map> A22row = annmap_; Teuchos::RCP<Epetra_CrsMatrix> A11 = Teuchos::null; Teuchos::RCP<Epetra_CrsMatrix> A12 = Teuchos::null; Teuchos::RCP<Epetra_CrsMatrix> A21 = Teuchos::null; Teuchos::RCP<Epetra_CrsMatrix> A22 = Teuchos::null; MOERTEL::SplitMatrix2x2(inputmatrix_,A11row,A22row,A11,A12,A21,A22); #endif #if 0 //-------------------------------------------------------------------------- // 1.7) create a shifted version of M and D Epetra_CrsMatrix* MTshifted = new Epetra_CrsMatrix(Copy,*annmap,1,false); Epetra_CrsMatrix* Dshifted = new Epetra_CrsMatrix(Copy,*annmap,1,false); std::vector<int> gindices(500); for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr) { const int lmdof = intintcurr->first; const int dof = intintcurr->second; if (D_->MyGRID(lmdof)==false) continue; const int lmlrid = D_->LRID(lmdof); int numentries; int* indices; double* values; // do D err = D_->ExtractMyRowView(lmlrid,numentries,values,indices); if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl; if (numentries>(int)gindices.size()) gindices.resize(numentries); for (int j=0; j<numentries; ++j) { gindices[j] = D_->GCID(indices[j]); if (gindices[j]<0) cout << "Cannot find gcid for indices[j]\n"; } err = Dshifted->InsertGlobalValues(dof,numentries,values,&gindices[0]); if (err<0) cout << "Dshifted->InsertGlobalValues returned err=" << err << endl; // do MT err = M_->ExtractMyRowView(lmlrid,numentries,values,indices); if (err) cout << "M_->ExtractMyRowView returned err=" << err << endl; if (numentries>(int)gindices.size()) gindices.resize(numentries); for (int j=0; j<numentries; ++j) { gindices[j] = M_->GCID(indices[j]); if (gindices[j]<0) cout << "Cannot find gcid for indices[j]\n"; } err = MTshifted->InsertGlobalValues(dof,numentries,values,&gindices[0]); if (err<0) cout << "MTshifted->InsertGlobalValues returned err=" << err << endl; } gindices.clear(); Dshifted->FillComplete(*problemmap_,*annmap); Dshifted->OptimizeStorage(); MTshifted->FillComplete(*problemmap_,*annmap); MTshifted->OptimizeStorage(); Dshifted_ = Teuchos::rcp(Dshifted); MTshifted_ = Teuchos::rcp(MTshifted); #endif //-------------------------------------------------------------------------- // 2) create WT, D and MT Epetra_CrsMatrix* WT = new Epetra_CrsMatrix(Copy,*annmap,1,false); for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr) { int lmdof = intintcurr->first; int dof = intintcurr->second; if (D_->MyGRID(lmdof)==false) continue; int lmlrid = D_->LRID(lmdof); int numentries; int* indices; double* values; err = D_->ExtractMyRowView(lmlrid,numentries,values,indices); if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl; bool foundit = false; for (int j=0; j<numentries; ++j) { int gcid = D_->GCID(indices[j]); if (gcid<0) cout << "Cannot find gcid for indices[j]\n"; //cout << "Proc " << Comm().MyPID() << " lmdof " << lmdof << " dof " << dof << " gcid " << gcid << " val " << values[j] << endl; if (gcid==dof) { double val = 1./values[j]; err = WT->InsertGlobalValues(dof,1,&val,&dof); if (err<0) cout << "WT->InsertGlobalValues returned err=" << err << endl; foundit = true; break; } } if (!foundit) { cout << "***ERR*** MOERTEL::Manager::MakeSPDProblem:\n" << "***ERR*** Cannot compute inverse of D_\n" << "***ERR*** file/line: " << __FILE__ << "/" << __LINE__ << "\n"; cout << "lmdof " << lmdof << " dof " << dof << endl; return NULL; } } WT->FillComplete(*problemmap_,*annmap); WT_ = Teuchos::rcp(WT); //-------------------------------------------------------------------------- // 3) create B // create a temporary matrix with rowmap of the Ann block Epetra_CrsMatrix* tmp = new Epetra_CrsMatrix(Copy,*annmap,120); std::vector<int> newindices(100); for (intintcurr=lm_to_dof.begin(); intintcurr!=lm_to_dof.end(); ++intintcurr) { int lmdof = intintcurr->first; int dof = intintcurr->second; if (D_->MyGRID(lmdof)==false) continue; int lmlrid = D_->LRID(lmdof); if (lmlrid<0) cout << "Cannot find lmlrid for lmdof\n"; int numentries; int* indices; double* values; // extract and add values from D err = D_->ExtractMyRowView(lmlrid,numentries,values,indices); if (err) cout << "D_->ExtractMyRowView returned err=" << err << endl; if (numentries>(int)newindices.size()) newindices.resize(numentries); for (int j=0; j<numentries; ++j) { newindices[j] = D_->GCID(indices[j]); if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n"; } //cout << "Inserting from D in row " << dof << " cols/val "; //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " "; //cout << endl; err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]); if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl; // extract and add values from M err = M_->ExtractMyRowView(lmlrid,numentries,values,indices); if (err) cout << "M_->ExtractMyRowView returned err=" << err << endl; if (numentries>(int)newindices.size()) newindices.resize(numentries); for (int j=0; j<numentries; ++j) { newindices[j] = M_->GCID(indices[j]); if (newindices[j]<0) cout << "Cannot find gcid for indices[j]\n"; } //cout << "Inserting from M in row " << dof << " cols/val "; //for (int j=0; j<numentries; ++j) cout << newindices[j] << "/" << values[j] << " "; //cout << endl; err = tmp->InsertGlobalValues(dof,numentries,values,&newindices[0]); if (err) cout << "tmp->InsertGlobalValues returned err=" << err << endl; } tmp->FillComplete(*(problemmap_.get()),*annmap); // B is transposed of tmp EpetraExt::RowMatrix_Transpose* trans = new EpetraExt::RowMatrix_Transpose(false); Epetra_CrsMatrix* B = &(dynamic_cast<Epetra_CrsMatrix&>(((*trans)(const_cast<Epetra_CrsMatrix&>(*tmp))))); delete tmp; tmp = NULL; B_ = Teuchos::rcp(new Epetra_CrsMatrix(*B)); newindices.clear(); //-------------------------------------------------------------------------- // 4) create I Epetra_CrsMatrix* I = new Epetra_CrsMatrix(Copy,*problemmap_,1,true); for (int i=0; i<I->NumMyRows(); ++i) { double one = 1.0; int grid = I->GRID(i); if (grid<0) cout << "Cannot find grid for i\n"; err = I->InsertGlobalValues(grid,1,&one,&grid); if (err<0) cout << "I->InsertGlobalValues returned err=" << err << endl; } I->FillComplete(*problemmap_,*problemmap_); I_ = Teuchos::rcp(I); //-------------------------------------------------------------------------- // 5) Build BWT = B * WT Epetra_CrsMatrix* BWT = MOERTEL::MatMatMult(*B,false,*WT,false,OutLevel()); //-------------------------------------------------------------------------- // 6) Build BWTmI = BWT - I Epetra_CrsMatrix* BWTmI = new Epetra_CrsMatrix(Copy,*problemmap_,10,false); MOERTEL::MatrixMatrixAdd(*BWT,false,1.0,*BWTmI,0.0); MOERTEL::MatrixMatrixAdd(*I,false,-1.0,*BWTmI,1.0); BWTmI->FillComplete(); //-------------------------------------------------------------------------- // 7) Build BWTmIAWBT = BWTmI * A * W * B^T Epetra_CrsMatrix* BWTmIA = MOERTEL::MatMatMult(*BWTmI,false,*inputmatrix_,false,OutLevel()); Epetra_CrsMatrix* WBT = MOERTEL::MatMatMult(*WT,true,*B,true,OutLevel()); Epetra_CrsMatrix* BWTmIAWBT = MOERTEL::MatMatMult(*BWTmIA,false,*WBT,false,OutLevel()); delete BWTmIA; BWTmIA = NULL; //-------------------------------------------------------------------------- // 8) Allocate spdmatrix_ and add A and BWTmIAWBT spdmatrix_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy,*problemmap_,10,false)); MOERTEL::MatrixMatrixAdd(*BWTmIAWBT,false,1.0,*spdmatrix_,0.0); delete BWTmIAWBT; BWTmIAWBT = NULL; MOERTEL::MatrixMatrixAdd(*inputmatrix_,false,1.0,*spdmatrix_,1.0); //-------------------------------------------------------------------------- // 9) Build WBTmI = WT^T * B^T - I Epetra_CrsMatrix* WBTmI = new Epetra_CrsMatrix(Copy,*problemmap_,10,false); MOERTEL::MatrixMatrixAdd(*I,false,-1.0,*WBTmI,0.0); MOERTEL::MatrixMatrixAdd(*WBT,false,1.0,*WBTmI,1.0); WBTmI->FillComplete(); delete WBT; WBT = NULL; //-------------------------------------------------------------------------- // 10) Build BWTAWBTmI = BWT * A * WBTmI and add to spdmatrix_ Epetra_CrsMatrix* BWTA = MOERTEL::MatMatMult(*BWT,false,*inputmatrix_,false,OutLevel()); Epetra_CrsMatrix* BWTAWBTmI = MOERTEL::MatMatMult(*BWTA,false,*WBTmI,false,OutLevel()); delete BWTA; BWTA = NULL; delete WBTmI; WBTmI = NULL; MOERTEL::MatrixMatrixAdd(*BWTAWBTmI,false,1.0,*spdmatrix_,1.0); delete BWTAWBTmI; BWTAWBTmI = NULL; spdmatrix_->FillComplete(); spdmatrix_->OptimizeStorage(); //-------------------------------------------------------------------------- // 11) Build ImBWT = I - BWT and store it as spdrhs_ spdrhs_ = Teuchos::rcp(new Epetra_CrsMatrix(Copy,*problemmap_,10,false)); MOERTEL::MatrixMatrixAdd(*I,false,1.0,*spdrhs_,0.0); //delete I; I = NULL; MOERTEL::MatrixMatrixAdd(*BWT,false,-1.0,*spdrhs_,1.0); delete BWT; BWT = NULL; spdrhs_->FillComplete(); spdrhs_->OptimizeStorage(); //-------------------------------------------------------------------------- // tidy up lm_to_dof.clear(); //delete annmap; //delete WT; WT = NULL; delete trans; B = NULL; // time this process double t = time.ElapsedTime(); if (OutLevel()>5 && Comm().MyPID()==0) cout << "MOERTEL (Proc 0): Construct spd system in " << t << " sec\n"; return spdmatrix_.get(); }
bool FiniteDifferenceColoringWithUpdate::differenceProbe(const Epetra_Vector& x, Epetra_CrsMatrix& jac,const Epetra_MapColoring& colors){ // Allocate space for perturbation, get column version of x for scaling Epetra_Vector xp(x); Epetra_Vector *xcol; int N=jac.NumMyRows(); if(jac.ColMap().SameAs(x.Map())) xcol=const_cast<Epetra_Vector*>(&x); else{ xcol=new Epetra_Vector(jac.ColMap(),true);//zeros out by default xcol->Import(x,*jac.Importer(),InsertAdd); } // Counters for probing diagnostics double tmp,probing_error_lower_bound=0.0,jc_norm=0.0; // Grab coloring info (being very careful to ignore color 0) int Ncolors=colors.MaxNumColors()+1; int num_c0_global,num_c0_local=colors.NumElementsWithColor(0); colors.Comm().MaxAll(&num_c0_local,&num_c0_global,1); if(num_c0_global>0) Ncolors--; if(Ncolors==0) return false; // Pointers for Matrix Info int entries, *indices; double *values; // NTS: Fix me if ( diffType == Centered ) exit(1); double scaleFactor = 1.0; if ( diffType == Backward ) scaleFactor = -1.0; // Compute RHS at initial solution computeF(x,fo,NOX::Epetra::Interface::Required::FD_Res); /* Probing, vector by vector since computeF does not have a MultiVector interface */ // Assume that anything with Color 0 gets ignored. for(int j=1;j<Ncolors;j++){ xp=x; for(int i=0;i<N;i++){ if(colors[i]==j) xp[i] += scaleFactor*(alpha*abs(x[i])+beta); } computeF(xp, fp, NOX::Epetra::Interface::Required::FD_Res); // Do the subtraction to estimate the Jacobian (w/o including step length) Jc.Update(1.0, fp, -1.0, fo, 0.0); // Relative error in probing if(use_probing_diags){ Jc.Norm2(&tmp); jc_norm+=tmp*tmp; } for(int i=0;i<N;i++){ // Skip for uncolored row/columns, else update entries if(colors[i]==0) continue; jac.ExtractMyRowView(i,entries,values,indices); for(int k=0;k<jac.NumMyEntries(i);k++){ if(colors[indices[k]]==j){ values[k]=Jc[i] / (scaleFactor*(alpha*abs((*xcol)[indices[k]])+beta)); // If probing diagnostics are on, zero out the entries as they are used if(use_probing_diags) Jc[i]=0.0; break;// Only one value per row... } } } if(use_probing_diags){ Jc.Norm2(&tmp); probing_error_lower_bound+=tmp*tmp; } } // If diagnostics are requested, output Frobenius norm lower bound if(use_probing_diags && !x.Comm().MyPID()) printf("Probing Error Lower Bound (Frobenius) abs = %6.4e rel = %6.4e\n",sqrt(probing_error_lower_bound),sqrt(probing_error_lower_bound)/sqrt(jc_norm)); // Cleanup if(!jac.ColMap().SameAs(x.Map())) delete xcol; return true; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif // get the epetra matrix from the Gallery int nx = 8; int ny = 8 * Comm.NumProc(); ParameterList GaleriList; GaleriList.set("nx", nx); GaleriList.set("ny", ny); GaleriList.set("mx", 1); GaleriList.set("my", Comm.NumProc()); Epetra_Map* Map = CreateMap("Cartesian2D", Comm, GaleriList); Epetra_CrsMatrix* A = CreateCrsMatrix("Laplace2D", Map, GaleriList); Epetra_Vector LHS(*Map); LHS.Random(); Epetra_Vector RHS(*Map); RHS.PutScalar(0.0); Epetra_LinearProblem Problem(A, &LHS, &RHS); AztecOO solver(Problem); Init(); try { Space S(-1, A->NumMyRows(), A->RowMatrixRowMap().MyGlobalElements()); Operator A_MLAPI(S, S, A, false); Teuchos::ParameterList MLList; MLList.set("max levels",3); MLList.set("increasing or decreasing","increasing"); MLList.set("aggregation: type", "Uncoupled"); MLList.set("aggregation: damping factor", 0.0); MLList.set("smoother: type","symmetric Gauss-Seidel"); MLList.set("smoother: sweeps",1); MLList.set("smoother: damping factor",1.0); MLList.set("coarse: max size",3); MLList.set("smoother: pre or post", "both"); MLList.set("coarse: type","Amesos-KLU"); MultiLevelSA Prec_MLAPI(A_MLAPI, MLList); Epetra_Operator* Prec = new EpetraBaseOperator(A->RowMatrixRowMap(), Prec_MLAPI); solver.SetPrecOperator(Prec); solver.SetAztecOption(AZ_solver, AZ_cg_condnum); solver.SetAztecOption(AZ_output, 32); solver.Iterate(500, 1e-12); // destroy the preconditioner delete Prec; } catch (const int e) { cerr << "Caught exception, code = " << e << endl; } catch (...) { cerr << "Caught exception..." << endl; } Finalize(); // compute the real residual double residual; LHS.Norm2(&residual); if( Comm.MyPID()==0 ) { cout << "||b-Ax||_2 = " << residual << endl; } delete A; delete Map; // for testing purposes if (residual > 1e-5) exit(EXIT_FAILURE); #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // Uncomment to debug in parallel int tmp; if (comm.MyPID()==0) cin >> tmp; comm.Barrier(); bool verbose = false; bool veryVerbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; if (!verbose) comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) cout << comm << endl << flush; bool verbose1 = verbose; if (verbose) verbose = (comm.MyPID()==0); int nx = 4; int ny = comm.NumProc()*nx; // Scale y grid with number of processors // Create funky stencil to make sure the matrix is non-symmetric (transpose non-trivial): // (i-1,j-1) (i-1,j ) // (i ,j-1) (i ,j ) (i ,j+1) // (i+1,j-1) (i+1,j ) int npoints = 2; int xoff[] = {-1, 0, 1, -1, 0, 1, 0}; int yoff[] = {-1, -1, -1, 0, 0, 0, 1}; Epetra_Map * map; Epetra_CrsMatrix * A; Epetra_Vector * x, * b, * xexact; Trilinos_Util_GenerateCrsProblem(nx, ny, npoints, xoff, yoff, comm, map, A, x, b, xexact); if (verbose) cout << "npoints = " << npoints << " nx = " << nx << " ny = " << ny << endl ; if (verbose && nx<6 ) { cout << *A << endl; cout << "B = " << endl << *b << endl; } // Construct linear problem object Epetra_LinearProblem origProblem(A, x, b); Epetra_LinearProblem *redistProblem; Epetra_Time timer(comm); // Construct redistor object, use all processors and replicate full problem on each double start = timer.ElapsedTime(); Epetra_LinearProblemRedistor redistor(&origProblem, comm.NumProc(), true); if (verbose) cout << "\nTime to construct redistor = " << timer.ElapsedTime() - start << endl; bool ConstructTranspose = true; bool MakeDataContiguous = true; start = timer.ElapsedTime(); redistor.CreateRedistProblem(ConstructTranspose, MakeDataContiguous, redistProblem); if (verbose) cout << "\nTime to create redistributed problem = " << timer.ElapsedTime() - start << endl; // Now test output of redistor by performing matvecs int ierr = 0; ierr += checkResults( ConstructTranspose, &redistor, &origProblem, redistProblem, verbose); // Now change values in original rhs and test update facility of redistor // Multiply b by 2 double Value = 2.0; b->Scale(Value); // b = 2*b redistor.UpdateRedistRHS(b); if (verbose) cout << "\nTime to update redistributed RHS = " << timer.ElapsedTime() - start << endl; ierr += checkResults( ConstructTranspose, &redistor, &origProblem, redistProblem, verbose); // Now change values in original matrix and test update facility of redistor #define CREATE_CONST_MATRIX #ifdef CREATE_CONST_MATRIX // The easiest way that I could find to change the matrix without EPETRA_CHK_ERRs A->PutScalar(13.0); #else // This has no effect on matrices, such as when nx = 4, that have no // diagonal entries. However, it does cause many EPETRA_CHK_ERR prints. // Add 2 to the diagonal of each row for (i=0; i< A->NumMyRows(); i++) { // for (i=0; i < 1; i++) cout << " i = " << i ; A->SumIntoMyValues(i, 1, &Value, &i); } #endif start = timer.ElapsedTime(); redistor.UpdateRedistProblemValues(&origProblem); if (verbose) cout << "\nTime to update redistributed problem = " << timer.ElapsedTime() - start << endl; ierr += checkResults(ConstructTranspose, &redistor, &origProblem, redistProblem, verbose); delete A; delete b; delete x; delete xexact; delete map; #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }
int main(int argc, char *argv[]) { #ifdef EPETRA_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif Epetra_Time Time(Comm); // Create the linear problem using the class `Trilinos_Util::CrsMatrixGallery.' // Various matrix examples are supported; please refer to the // Trilinos tutorial for more details. // create Aztec stuff int proc_config[AZ_PROC_SIZE], options[AZ_OPTIONS_SIZE]; #ifdef ML_MPI /* get number of processors and the name of this processor */ AZ_set_proc_config(proc_config, MPI_COMM_WORLD); int proc = proc_config[AZ_node]; int nprocs = proc_config[AZ_N_procs]; #else AZ_set_proc_config(proc_config, AZ_NOT_MPI); int proc = 0; int nprocs = 1; #endif // read in the matrix size FILE *fp = fopen("ExampleMatrices/cantilever2D/data_matrix.txt","r"); int leng; fscanf(fp,"%d",&leng); int num_PDE_eqns=2; int N_grid_pts = leng/num_PDE_eqns; // make a linear distribution of the matrix respecting the blocks size int leng1 = leng/nprocs; int leng2 = leng-leng1*nprocs; if (proc >= leng2) { leng2 += (proc*leng1); } else { leng1++; leng2 = proc*leng1; } int N_update = leng1; int* update = new int[N_update+1]; int i; double *val=NULL; int *bindx=NULL; for (i=0; i<N_update; i++) update[i] = i+leng2; // create the Epetra_CrSMatrix Epetra_Map* StandardMap = new Epetra_Map(leng,N_update,update,0,Comm); Epetra_CrsMatrix* A = new Epetra_CrsMatrix(Copy,*StandardMap,1); AZ_input_msr_matrix("ExampleMatrices/cantilever2D/data_matrix.txt", update, &val, &bindx, N_update, proc_config); for (i=0; i<leng; i++) { int row = update[i]; A->SumIntoGlobalValues(row,1,&(val[i]),&row); A->SumIntoGlobalValues(row,bindx[i+1]-bindx[i],&(val[bindx[i]]),&(bindx[bindx[i]])); } A->TransformToLocal(); // create solution and right-hand side (MultiVectors are fine as well) Epetra_Vector* LHS = new Epetra_Vector(A->OperatorDomainMap()); Epetra_Vector* RHS = new Epetra_Vector(A->OperatorRangeMap()); LHS->Random(); RHS->Random(); // build the epetra linear problem Epetra_LinearProblem Problem(A, LHS, RHS); // Construct a solver object for this problem AztecOO solver(Problem); // =========================== begin of ML part =========================== // create a parameter list for ML options ParameterList MLList; // set defaults for classic smoothed aggregation ML_Epetra::SetDefaults("SA",MLList); MLList.set("aggregation: damping factor", 0.0); // number of relaxation sweeps MLList.set("adaptive: max sweeps", 10); // number of additional null space vectors to compute MLList.set("adaptive: num vectors",2); #if 1 ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList, false); // need to allocate and fill the null space (also the // default one, as in this case). This vector is no longer // needed after a call to ComputeAdaptivePreconditioner(). int NullSpaceSize = 2; vector<double> NullSpace((NullSpaceSize*A->NumMyRows())); for (i = 0 ; i < A->NumMyRows() ; ++i) { NullSpace[i] = 1.0; ++i; NullSpace[i] = 0.0; } for (i = A->NumMyRows() ; i < 2*A->NumMyRows() ; ++i) { NullSpace[i] = 0.0; ++i; NullSpace[i] = 1.0; } MLPrec->ComputeAdaptivePreconditioner(NullSpaceSize,&NullSpace[0]); #else ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(dynamic_cast<Epetra_RowMatrix&>(*A), MLList); #endif // tell AztecOO to use this preconditioner, then solve solver.SetPrecOperator(MLPrec); // =========================== end of ML part ============================= solver.SetAztecOption(AZ_solver, AZ_gmres); solver.SetAztecOption(AZ_output, 32); // solve with 500 iterations and 1e-12 tolerance solver.Iterate(1550, 1e-5); delete MLPrec; // compute the real residual double residual, diff; if( Comm.MyPID()==0 ) { cout << "||b-Ax||_2 = " << residual << endl; cout << "||x_exact - x||_2 = " << diff << endl; cout << "Total Time = " << Time.ElapsedTime() << endl; } #ifdef EPETRA_MPI MPI_Finalize(); #endif return(0); }
int check(Epetra_CrsMatrix& A, int NumMyRows1, int NumGlobalRows1, int NumMyNonzeros1, int NumGlobalNonzeros1, int* MyGlobalElements, bool verbose) { (void)MyGlobalElements; int ierr = 0, forierr = 0; int NumGlobalIndices; int NumMyIndices; int* MyViewIndices = 0; int* GlobalViewIndices = 0; double* MyViewValues = 0; double* GlobalViewValues = 0; int MaxNumIndices = A.Graph().MaxNumIndices(); int* MyCopyIndices = new int[MaxNumIndices]; int* GlobalCopyIndices = new int[MaxNumIndices]; double* MyCopyValues = new double[MaxNumIndices]; double* GlobalCopyValues = new double[MaxNumIndices]; // Test query functions int NumMyRows = A.NumMyRows(); if (verbose) cout << "\n\nNumber of local Rows = " << NumMyRows << endl<< endl; EPETRA_TEST_ERR(!(NumMyRows==NumMyRows1),ierr); int NumMyNonzeros = A.NumMyNonzeros(); if (verbose) cout << "\n\nNumber of local Nonzero entries = " << NumMyNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumMyNonzeros==NumMyNonzeros1),ierr); int NumGlobalRows = A.NumGlobalRows(); if (verbose) cout << "\n\nNumber of global Rows = " << NumGlobalRows << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalRows==NumGlobalRows1),ierr); int NumGlobalNonzeros = A.NumGlobalNonzeros(); if (verbose) cout << "\n\nNumber of global Nonzero entries = " << NumGlobalNonzeros << endl<< endl; EPETRA_TEST_ERR(!(NumGlobalNonzeros==NumGlobalNonzeros1),ierr); // GlobalRowView should be illegal (since we have local indices) EPETRA_TEST_ERR(!(A.ExtractGlobalRowView(A.RowMap().MaxMyGID(), NumGlobalIndices, GlobalViewValues, GlobalViewIndices)==-2),ierr); // Other binary tests EPETRA_TEST_ERR(A.NoDiagonal(),ierr); EPETRA_TEST_ERR(!(A.Filled()),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MaxMyGID())),ierr); EPETRA_TEST_ERR(!(A.MyGRID(A.RowMap().MinMyGID())),ierr); EPETRA_TEST_ERR(A.MyGRID(1+A.RowMap().MaxMyGID()),ierr); EPETRA_TEST_ERR(A.MyGRID(-1+A.RowMap().MinMyGID()),ierr); EPETRA_TEST_ERR(!(A.MyLRID(0)),ierr); EPETRA_TEST_ERR(!(A.MyLRID(NumMyRows-1)),ierr); EPETRA_TEST_ERR(A.MyLRID(-1),ierr); EPETRA_TEST_ERR(A.MyLRID(NumMyRows),ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowView(i, NumMyIndices, MyViewValues, MyViewIndices); // this is where the problem comes from forierr += !(NumGlobalIndices == NumMyIndices); for(int j = 1; j < NumMyIndices; j++) { forierr += !(MyViewIndices[j-1] < MyViewIndices[j]); // this is where the test fails } for(int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyViewIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyViewIndices[j]); forierr += !(GlobalCopyValues[j] == MyViewValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); forierr = 0; for (int i = 0; i < NumMyRows; i++) { int Row = A.GRID(i); A.ExtractGlobalRowCopy(Row, MaxNumIndices, NumGlobalIndices, GlobalCopyValues, GlobalCopyIndices); A.ExtractMyRowCopy(i, MaxNumIndices, NumMyIndices, MyCopyValues, MyCopyIndices); forierr += !(NumGlobalIndices == NumMyIndices); for (int j = 1; j < NumMyIndices; j++) forierr += !(MyCopyIndices[j-1] < MyCopyIndices[j]); for (int j = 0; j < NumGlobalIndices; j++) { forierr += !(GlobalCopyIndices[j] == A.GCID(MyCopyIndices[j])); forierr += !(A.LCID(GlobalCopyIndices[j]) == MyCopyIndices[j]); forierr += !(GlobalCopyValues[j] == MyCopyValues[j]); } } EPETRA_TEST_ERR(forierr,ierr); delete [] MyCopyIndices; delete [] GlobalCopyIndices; delete [] MyCopyValues; delete [] GlobalCopyValues; if (verbose) cout << "\n\nRows sorted check OK" << endl<< endl; return (ierr); }
int NOX::Epetra::TestCompare::testCrsMatrices( const Epetra_CrsMatrix& mat , const Epetra_CrsMatrix& mat_expected , double rtol, double atol , const std::string& name , bool enforceStructure ) { if (utils.isPrintType(NOX::Utils::TestDetails)) os << std::endl << "\tChecking " << name << ": "; int passed = 0; if( !mat_expected.RowMap().SameAs( mat.RowMap() ) ) { passed = 1; os << "Failed." << std::endl; os << std::endl << "\t\tRow maps are not compatible." << std::endl; return passed; } int numEntries1, numEntries2 ; int * columns1 , * columns2 ; double * values1 , * values2 ; int chkSize = 0 ; double maxVal = 0.0 ; double infNorm = 0.0 ; for( int row = 0; row < mat_expected.NumMyRows(); ++row ) { mat_expected.ExtractMyRowView(row, numEntries1, values1, columns1); mat.ExtractMyRowView (row, numEntries2, values2, columns2); if( numEntries1 != numEntries2 ) { if( enforceStructure ) { os << std::endl << "\t\t\t"; } else os << std::endl << "\t\tWARNING: "; os << "Matrix size is incompatible for Local Row " << row << "\n\t\t\t..... expected " << numEntries1 << " columns, found " << numEntries2 << std::endl; chkSize = 1; } mat.Comm().SumAll( &chkSize, &passed, 1 ); if( 0 != passed ) { if( enforceStructure ) { os << "Failed." << std::endl; return passed; } else { chkSize = 0; passed = 0; } } // Comapre column indices and values int baseCol = 0 ; int testCol = 0 ; int chkCol = 0 ; double baseVal = 0.0 ; double testVal = 0.0 ; double chkVal = 0.0 ; for( int col = 0; col < numEntries1; ++col ) { baseCol = columns1[col]; testCol = columns2[col]; baseVal = values1 [col]; testVal = values2 [col]; if( baseCol != testCol ) { if( enforceStructure ) { os << std::endl << "\t\t\t"; } else os << std::endl << "\t\tWARNING: "; os << "Column index for Local Row " << row << " is incompatible." << "\n\t\t\t..... expected " << baseCol << " , found " << testCol << std::endl; chkCol = 1; } mat.Comm().SumAll( &chkCol, &passed, 1 ); if( 0 != passed ) { if( enforceStructure ) { os << "Failed." << std::endl; return passed; } else { chkCol = 0; passed = 0; continue; // skip pvalue check } } chkVal = fabs( testVal - baseVal ) / (atol + rtol * fabs(baseVal)); mat.Comm().MaxAll( &chkVal, &maxVal, 1 ); if( maxVal > infNorm ) infNorm = maxVal; if( 1 < maxVal ) break; } if( 1 < maxVal ) break; } if( 1 < maxVal ) passed = 1; // false by convention in NOX::TestCompare else passed = 0; // true by convention in NOX::TestCompare if (utils.isPrintType(NOX::Utils::TestDetails)) { if( 0 == passed) os << "Passed." << std::endl; else os << "Failed." << std::endl; os << "\t\tComputed norm: " << utils.sciformat(infNorm) << std::endl << "\t\tRelative Tolerance: " << utils.sciformat(rtol) << std::endl << "\t\tAbsolute Tolerance: " << utils.sciformat(rtol) << std::endl; } return passed; }
int main(int argc, char *argv[]) { #ifdef HAVE_MPI MPI_Init(&argc,&argv); Epetra_MpiComm Comm(MPI_COMM_WORLD); #else Epetra_SerialComm Comm; #endif #define ML_SCALING #ifdef ML_SCALING const int ntimers=4; enum {total, probBuild, precBuild, solve}; ml_DblLoc timeVec[ntimers], maxTime[ntimers], minTime[ntimers]; for (int i=0; i<ntimers; i++) timeVec[i].rank = Comm.MyPID(); timeVec[total].value = MPI_Wtime(); #endif int nx; if (argc > 1) nx = (int) strtol(argv[1],NULL,10); else nx = 256; if (nx < 1) nx = 256; // input a nonpositive integer if you want to specify // the XML input file name. nx = nx*(int)sqrt((double)Comm.NumProc()); int ny = nx; printf("nx = %d\nny = %d\n",nx,ny); fflush(stdout); char xmlFile[80]; bool readXML=false; if (argc > 2) {strcpy(xmlFile,argv[2]); readXML = true;} else sprintf(xmlFile,"%s","params.xml"); ParameterList GaleriList; GaleriList.set("nx", nx); GaleriList.set("ny", ny); #ifdef ML_SCALING timeVec[probBuild].value = MPI_Wtime(); #endif Epetra_Map* Map = CreateMap("Cartesian2D", Comm, GaleriList); Epetra_CrsMatrix* A = CreateCrsMatrix("Laplace2D", Map, GaleriList); if (!Comm.MyPID()) printf("nx = %d, ny = %d, mx = %d, my = %d\n",nx,ny,GaleriList.get("mx",-1),GaleriList.get("my",-1)); fflush(stdout); //avoid potential overflow double numMyRows = A->NumMyRows(); double numGlobalRows; Comm.SumAll(&numMyRows,&numGlobalRows,1); if (!Comm.MyPID()) printf("# global rows = %1.0f\n",numGlobalRows); //printf("pid %d: #rows = %d\n",Comm.MyPID(),A->NumMyRows()); fflush(stdout); Epetra_MultiVector *coords = CreateCartesianCoordinates("2D", Map,GaleriList); double *x_coord=0,*y_coord=0,*z_coord=0; double **ttt; if (!coords->ExtractView(&ttt)) { x_coord = ttt[0]; y_coord = ttt[1]; } else { if (!Comm.MyPID()) printf("Error extracting coordinate vectors\n"); MPI_Finalize(); exit(EXIT_FAILURE); } Epetra_Vector LHS(*Map); LHS.Random(); Epetra_Vector RHS(*Map); RHS.PutScalar(0.0); Epetra_LinearProblem Problem(A, &LHS, &RHS); AztecOO solver(Problem); #ifdef ML_SCALING timeVec[probBuild].value = MPI_Wtime() - timeVec[probBuild].value; #endif // =========================== begin of ML part =========================== #ifdef ML_SCALING timeVec[precBuild].value = MPI_Wtime(); #endif ParameterList MLList; if (readXML) { MLList.set("read XML",true); MLList.set("XML input file",xmlFile); } else { cout << "here" << endl; ML_Epetra::SetDefaults("SA",MLList); MLList.set("smoother: type","Chebyshev"); MLList.set("smoother: sweeps",3); MLList.set("coarse: max size",1); } MLList.set("x-coordinates", x_coord); MLList.set("y-coordinates", y_coord); MLList.set("z-coordinates", z_coord); /* RCP<std::vector<int> > m_smootherAztecOptions = rcp(new std::vector<int>(AZ_OPTIONS_SIZE)); RCP<std::vector<double> > m_smootherAztecParams = rcp(new std::vector<double>(AZ_PARAMS_SIZE)); //int m_smootherAztecOptions[AZ_OPTIONS_SIZE]; //double m_smootherAztecParams[AZ_PARAMS_SIZE]; std::string smootherType("Aztec"); AZ_defaults(&(*m_smootherAztecOptions)[0],&(*m_smootherAztecParams)[0]); (*m_smootherAztecOptions)[AZ_precond] = AZ_dom_decomp; (*m_smootherAztecOptions)[AZ_subdomain_solve] = AZ_icc; bool smootherAztecAsSolver = true; */ MLList.set("ML output",10); MLList.set("repartition: enable",1); MLList.set("repartition: max min ratio",1.3); MLList.set("repartition: min per proc",200); MLList.set("repartition: partitioner","Zoltan"); MLList.set("repartition: Zoltan dimensions",2); MLList.set("repartition: put on single proc",1); MLList.set("repartition: Zoltan type","hypergraph"); MLList.set("repartition: estimated iterations",13); /* MLList.set("smoother: Aztec options",m_smootherAztecOptions); MLList.set("smoother: Aztec params",m_smootherAztecParams); MLList.set("smoother: type",smootherType.c_str()); MLList.set("smoother: Aztec as solver", smootherAztecAsSolver); MLList.set("ML print initial list", 0); MLList.set("ML print final list", 0); */ ML_Epetra::MultiLevelPreconditioner* MLPrec = new ML_Epetra::MultiLevelPreconditioner(*A, MLList); // verify unused parameters on process 0 (put -1 to print on all // processes) MLPrec->PrintUnused(0); #ifdef ML_SCALING timeVec[precBuild].value = MPI_Wtime() - timeVec[precBuild].value; #endif // =========================== end of ML part ============================= #ifdef ML_SCALING timeVec[solve].value = MPI_Wtime(); #endif solver.SetPrecOperator(MLPrec); solver.SetAztecOption(AZ_solver, AZ_cg); solver.SetAztecOption(AZ_output, 1); solver.Iterate(500, 1e-12); #ifdef ML_SCALING timeVec[solve].value = MPI_Wtime() - timeVec[solve].value; #endif // destroy the preconditioner delete MLPrec; // compute the real residual double residual; LHS.Norm2(&residual); if( Comm.MyPID()==0 ) { cout << "||b-Ax||_2 = " << residual << endl; } // for testing purposes if (residual > 1e-5) exit(EXIT_FAILURE); delete A; delete Map; delete coords; #ifdef ML_SCALING timeVec[total].value = MPI_Wtime() - timeVec[total].value; //avg double dupTime[ntimers],avgTime[ntimers]; for (int i=0; i<ntimers; i++) dupTime[i] = timeVec[i].value; MPI_Reduce(dupTime,avgTime,ntimers,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); for (int i=0; i<ntimers; i++) avgTime[i] = avgTime[i]/Comm.NumProc(); //min MPI_Reduce(timeVec,minTime,ntimers,MPI_DOUBLE_INT,MPI_MINLOC,0,MPI_COMM_WORLD); //max MPI_Reduce(timeVec,maxTime,ntimers,MPI_DOUBLE_INT,MPI_MAXLOC,0,MPI_COMM_WORLD); if (Comm.MyPID() == 0) { printf("timing : max (pid) min (pid) avg\n"); printf("Problem build : %2.3e (%d) %2.3e (%d) %2.3e \n", maxTime[probBuild].value,maxTime[probBuild].rank, minTime[probBuild].value,minTime[probBuild].rank, avgTime[probBuild]); printf("Preconditioner build : %2.3e (%d) %2.3e (%d) %2.3e \n", maxTime[precBuild].value,maxTime[precBuild].rank, minTime[precBuild].value,minTime[precBuild].rank, avgTime[precBuild]); printf("Solve : %2.3e (%d) %2.3e (%d) %2.3e \n", maxTime[solve].value,maxTime[solve].rank, minTime[solve].value,minTime[solve].rank, avgTime[solve]); printf("Total : %2.3e (%d) %2.3e (%d) %2.3e \n", maxTime[total].value,maxTime[total].rank, minTime[total].value,minTime[total].rank, avgTime[total]); } #endif #ifdef HAVE_MPI MPI_Finalize(); #endif return(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { int i; #ifdef EPETRA_MPI // Initialize MPI MPI_Init(&argc,&argv); Epetra_MpiComm comm(MPI_COMM_WORLD); #else Epetra_SerialComm comm; #endif // Uncomment to debug in parallel int tmp; if (comm.MyPID()==0) cin >> tmp; comm.Barrier(); bool verbose = false; // Check if we should print results to standard out if (argc>1) if (argv[1][0]=='-' && argv[1][1]=='v') verbose = true; if (!verbose) comm.SetTracebackMode(0); // This should shut down any error traceback reporting if (verbose) cout << comm << endl << flush; if (verbose) verbose = (comm.MyPID()==0); if (verbose) cout << EpetraExt::EpetraExt_Version() << endl << endl; int nx = 128; int ny = comm.NumProc()*nx; // Scale y grid with number of processors // Create funky stencil to make sure the matrix is non-symmetric (transpose non-trivial): // (i-1,j-1) (i-1,j ) // (i ,j-1) (i ,j ) (i ,j+1) // (i+1,j-1) (i+1,j ) int npoints = 7; int xoff[] = {-1, 0, 1, -1, 0, 1, 0}; int yoff[] = {-1, -1, -1, 0, 0, 0, 1}; Epetra_Map * map; Epetra_CrsMatrix * A; Epetra_Vector * x, * b, * xexact; Trilinos_Util_GenerateCrsProblem(nx, ny, npoints, xoff, yoff, comm, map, A, x, b, xexact); if (nx<8) { cout << *A << endl; cout << "X exact = " << endl << *xexact << endl; cout << "B = " << endl << *b << endl; } // Construct transposer Epetra_Time timer(comm); double start = timer.ElapsedTime(); //bool IgnoreNonLocalCols = false; bool MakeDataContiguous = true; EpetraExt::RowMatrix_Transpose transposer( MakeDataContiguous ); if (verbose) cout << "\nTime to construct transposer = " << timer.ElapsedTime() - start << endl; Epetra_CrsMatrix & transA = dynamic_cast<Epetra_CrsMatrix&>(transposer(*A)); start = timer.ElapsedTime(); if (verbose) cout << "\nTime to create transpose matrix = " << timer.ElapsedTime() - start << endl; // Now test output of transposer by performing matvecs int ierr = 0; ierr += checkResults(A, &transA, xexact, verbose); // Now change values in original matrix and test update facility of transposer // Add 2 to the diagonal of each row double Value = 2.0; for (i=0; i< A->NumMyRows(); i++) A->SumIntoMyValues(i, 1, &Value, &i); start = timer.ElapsedTime(); transposer.fwd(); if (verbose) cout << "\nTime to update transpose matrix = " << timer.ElapsedTime() - start << endl; ierr += checkResults(A, &transA, xexact, verbose); delete A; delete b; delete x; delete xexact; delete map; if (verbose) cout << endl << "Checking transposer for VbrMatrix objects" << endl<< endl; int nsizes = 4; int sizes[] = {4, 6, 5, 3}; Epetra_VbrMatrix * Avbr; Epetra_BlockMap * bmap; Trilinos_Util_GenerateVbrProblem(nx, ny, npoints, xoff, yoff, nsizes, sizes, comm, bmap, Avbr, x, b, xexact); if (nx<8) { cout << *Avbr << endl; cout << "X exact = " << endl << *xexact << endl; cout << "B = " << endl << *b << endl; } start = timer.ElapsedTime(); EpetraExt::RowMatrix_Transpose transposer1( MakeDataContiguous ); Epetra_CrsMatrix & transA1 = dynamic_cast<Epetra_CrsMatrix&>(transposer1(*Avbr)); if (verbose) cout << "\nTime to create transpose matrix = " << timer.ElapsedTime() - start << endl; // Now test output of transposer by performing matvecs ; ierr += checkResults(Avbr, &transA1, xexact, verbose); // Now change values in original matrix and test update facility of transposer // Scale matrix on the left by rowsums Epetra_Vector invRowSums(Avbr->RowMap()); Avbr->InvRowSums(invRowSums); Avbr->LeftScale(invRowSums); start = timer.ElapsedTime(); transposer1.fwd(); if (verbose) cout << "\nTime to update transpose matrix = " << timer.ElapsedTime() - start << endl; ierr += checkResults(Avbr, &transA1, xexact, verbose); delete Avbr; delete b; delete x; delete xexact; delete bmap; #ifdef EPETRA_MPI MPI_Finalize(); #endif return ierr; }